Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

IB/core: Replace ib_umem's offset field with a full address

In order to allow umems that do not pin memory, we need the umem to
keep track of its region's address.

This makes the offset field redundant, and so this patch removes it.

Signed-off-by: Haggai Eran <haggaie@mellanox.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>

authored by

Haggai Eran and committed by
Roland Dreier
406f9e5f 968e78dd

+35 -12
+3 -3
drivers/infiniband/core/umem.c
··· 103 103 104 104 umem->context = context; 105 105 umem->length = size; 106 - umem->offset = addr & ~PAGE_MASK; 106 + umem->address = addr; 107 107 umem->page_size = PAGE_SIZE; 108 108 umem->pid = get_task_pid(current, PIDTYPE_PID); 109 109 /* ··· 132 132 if (!vma_list) 133 133 umem->hugetlb = 0; 134 134 135 - npages = PAGE_ALIGN(size + umem->offset) >> PAGE_SHIFT; 135 + npages = ib_umem_num_pages(umem); 136 136 137 137 down_write(&current->mm->mmap_sem); 138 138 ··· 246 246 if (!mm) 247 247 goto out; 248 248 249 - diff = PAGE_ALIGN(umem->length + umem->offset) >> PAGE_SHIFT; 249 + diff = ib_umem_num_pages(umem); 250 250 251 251 /* 252 252 * We may be called with the mm's mmap_sem already held. This
+1 -1
drivers/infiniband/hw/amso1100/c2_provider.c
··· 476 476 c2mr->umem->page_size, 477 477 i, 478 478 length, 479 - c2mr->umem->offset, 479 + ib_umem_offset(c2mr->umem), 480 480 &kva, 481 481 c2_convert_access(acc), 482 482 c2mr);
+1 -1
drivers/infiniband/hw/ehca/ehca_mrmw.c
··· 399 399 pginfo.num_kpages = num_kpages; 400 400 pginfo.num_hwpages = num_hwpages; 401 401 pginfo.u.usr.region = e_mr->umem; 402 - pginfo.next_hwpage = e_mr->umem->offset / hwpage_size; 402 + pginfo.next_hwpage = ib_umem_offset(e_mr->umem) / hwpage_size; 403 403 pginfo.u.usr.next_sg = pginfo.u.usr.region->sg_head.sgl; 404 404 ret = ehca_reg_mr(shca, e_mr, (u64 *)virt, length, mr_access_flags, 405 405 e_pd, &pginfo, &e_mr->ib.ib_mr.lkey,
+1 -1
drivers/infiniband/hw/ipath/ipath_mr.c
··· 214 214 mr->mr.user_base = start; 215 215 mr->mr.iova = virt_addr; 216 216 mr->mr.length = length; 217 - mr->mr.offset = umem->offset; 217 + mr->mr.offset = ib_umem_offset(umem); 218 218 mr->mr.access_flags = mr_access_flags; 219 219 mr->mr.max_segs = n; 220 220 mr->umem = umem;
+3 -3
drivers/infiniband/hw/nes/nes_verbs.c
··· 2341 2341 nes_debug(NES_DBG_MR, "User base = 0x%lX, Virt base = 0x%lX, length = %u," 2342 2342 " offset = %u, page size = %u.\n", 2343 2343 (unsigned long int)start, (unsigned long int)virt, (u32)length, 2344 - region->offset, region->page_size); 2344 + ib_umem_offset(region), region->page_size); 2345 2345 2346 - skip_pages = ((u32)region->offset) >> 12; 2346 + skip_pages = ((u32)ib_umem_offset(region)) >> 12; 2347 2347 2348 2348 if (ib_copy_from_udata(&req, udata, sizeof(req))) { 2349 2349 ib_umem_release(region); ··· 2408 2408 region_length -= skip_pages << 12; 2409 2409 for (page_index = skip_pages; page_index < chunk_pages; page_index++) { 2410 2410 skip_pages = 0; 2411 - if ((page_count != 0) && (page_count<<12)-(region->offset&(4096-1)) >= region->length) 2411 + if ((page_count != 0) && (page_count << 12) - (ib_umem_offset(region) & (4096 - 1)) >= region->length) 2412 2412 goto enough_pages; 2413 2413 if ((page_count&0x01FF) == 0) { 2414 2414 if (page_count >= 1024 * 512) {
+1 -1
drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
··· 805 805 goto umem_err; 806 806 807 807 mr->hwmr.pbe_size = mr->umem->page_size; 808 - mr->hwmr.fbo = mr->umem->offset; 808 + mr->hwmr.fbo = ib_umem_offset(mr->umem); 809 809 mr->hwmr.va = usr_addr; 810 810 mr->hwmr.len = len; 811 811 mr->hwmr.remote_wr = (acc & IB_ACCESS_REMOTE_WRITE) ? 1 : 0;
+1 -1
drivers/infiniband/hw/qib/qib_mr.c
··· 258 258 mr->mr.user_base = start; 259 259 mr->mr.iova = virt_addr; 260 260 mr->mr.length = length; 261 - mr->mr.offset = umem->offset; 261 + mr->mr.offset = ib_umem_offset(umem); 262 262 mr->mr.access_flags = mr_access_flags; 263 263 mr->umem = umem; 264 264
+24 -1
include/rdma/ib_umem.h
··· 42 42 struct ib_umem { 43 43 struct ib_ucontext *context; 44 44 size_t length; 45 - int offset; 45 + unsigned long address; 46 46 int page_size; 47 47 int writable; 48 48 int hugetlb; ··· 54 54 int nmap; 55 55 int npages; 56 56 }; 57 + 58 + /* Returns the offset of the umem start relative to the first page. */ 59 + static inline int ib_umem_offset(struct ib_umem *umem) 60 + { 61 + return umem->address & ((unsigned long)umem->page_size - 1); 62 + } 63 + 64 + /* Returns the first page of an ODP umem. */ 65 + static inline unsigned long ib_umem_start(struct ib_umem *umem) 66 + { 67 + return umem->address - ib_umem_offset(umem); 68 + } 69 + 70 + /* Returns the address of the page after the last one of an ODP umem. */ 71 + static inline unsigned long ib_umem_end(struct ib_umem *umem) 72 + { 73 + return PAGE_ALIGN(umem->address + umem->length); 74 + } 75 + 76 + static inline size_t ib_umem_num_pages(struct ib_umem *umem) 77 + { 78 + return (ib_umem_end(umem) - ib_umem_start(umem)) >> PAGE_SHIFT; 79 + } 57 80 58 81 #ifdef CONFIG_INFINIBAND_USER_MEM 59 82