aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHaggai Eran <haggaie@mellanox.com>2014-12-11 10:04:12 -0500
committerRoland Dreier <roland@purestorage.com>2014-12-15 21:13:35 -0500
commit406f9e5fa9a7a60b42e676841e39f2d752266814 (patch)
treeea6b1776793ed0ae3079d9860132a9e062801b18
parent968e78dd96443e2cc963c493070574778805e76a (diff)
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>
-rw-r--r--drivers/infiniband/core/umem.c6
-rw-r--r--drivers/infiniband/hw/amso1100/c2_provider.c2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_mrmw.c2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_mr.c2
-rw-r--r--drivers/infiniband/hw/nes/nes_verbs.c6
-rw-r--r--drivers/infiniband/hw/ocrdma/ocrdma_verbs.c2
-rw-r--r--drivers/infiniband/hw/qib/qib_mr.c2
-rw-r--r--include/rdma/ib_umem.h25
8 files changed, 35 insertions, 12 deletions
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
index df0c4f605a21..e0f883292374 100644
--- a/drivers/infiniband/core/umem.c
+++ b/drivers/infiniband/core/umem.c
@@ -103,7 +103,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
103 103
104 umem->context = context; 104 umem->context = context;
105 umem->length = size; 105 umem->length = size;
106 umem->offset = addr & ~PAGE_MASK; 106 umem->address = addr;
107 umem->page_size = PAGE_SIZE; 107 umem->page_size = PAGE_SIZE;
108 umem->pid = get_task_pid(current, PIDTYPE_PID); 108 umem->pid = get_task_pid(current, PIDTYPE_PID);
109 /* 109 /*
@@ -132,7 +132,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
132 if (!vma_list) 132 if (!vma_list)
133 umem->hugetlb = 0; 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 down_write(&current->mm->mmap_sem); 137 down_write(&current->mm->mmap_sem);
138 138
@@ -246,7 +246,7 @@ void ib_umem_release(struct ib_umem *umem)
246 if (!mm) 246 if (!mm)
247 goto out; 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 * We may be called with the mm's mmap_sem already held. This 252 * We may be called with the mm's mmap_sem already held. This
diff --git a/drivers/infiniband/hw/amso1100/c2_provider.c b/drivers/infiniband/hw/amso1100/c2_provider.c
index 2d5cbf4363e4..bdf3507810cb 100644
--- a/drivers/infiniband/hw/amso1100/c2_provider.c
+++ b/drivers/infiniband/hw/amso1100/c2_provider.c
@@ -476,7 +476,7 @@ static struct ib_mr *c2_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
476 c2mr->umem->page_size, 476 c2mr->umem->page_size,
477 i, 477 i,
478 length, 478 length,
479 c2mr->umem->offset, 479 ib_umem_offset(c2mr->umem),
480 &kva, 480 &kva,
481 c2_convert_access(acc), 481 c2_convert_access(acc),
482 c2mr); 482 c2mr);
diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c
index 3488e8c9fcb4..f914b30999f8 100644
--- a/drivers/infiniband/hw/ehca/ehca_mrmw.c
+++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c
@@ -399,7 +399,7 @@ reg_user_mr_fallback:
399 pginfo.num_kpages = num_kpages; 399 pginfo.num_kpages = num_kpages;
400 pginfo.num_hwpages = num_hwpages; 400 pginfo.num_hwpages = num_hwpages;
401 pginfo.u.usr.region = e_mr->umem; 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 pginfo.u.usr.next_sg = pginfo.u.usr.region->sg_head.sgl; 403 pginfo.u.usr.next_sg = pginfo.u.usr.region->sg_head.sgl;
404 ret = ehca_reg_mr(shca, e_mr, (u64 *)virt, length, mr_access_flags, 404 ret = ehca_reg_mr(shca, e_mr, (u64 *)virt, length, mr_access_flags,
405 e_pd, &pginfo, &e_mr->ib.ib_mr.lkey, 405 e_pd, &pginfo, &e_mr->ib.ib_mr.lkey,
diff --git a/drivers/infiniband/hw/ipath/ipath_mr.c b/drivers/infiniband/hw/ipath/ipath_mr.c
index 5e61e9bff697..c7278f6a8217 100644
--- a/drivers/infiniband/hw/ipath/ipath_mr.c
+++ b/drivers/infiniband/hw/ipath/ipath_mr.c
@@ -214,7 +214,7 @@ struct ib_mr *ipath_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
214 mr->mr.user_base = start; 214 mr->mr.user_base = start;
215 mr->mr.iova = virt_addr; 215 mr->mr.iova = virt_addr;
216 mr->mr.length = length; 216 mr->mr.length = length;
217 mr->mr.offset = umem->offset; 217 mr->mr.offset = ib_umem_offset(umem);
218 mr->mr.access_flags = mr_access_flags; 218 mr->mr.access_flags = mr_access_flags;
219 mr->mr.max_segs = n; 219 mr->mr.max_segs = n;
220 mr->umem = umem; 220 mr->umem = umem;
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c
index fef067c959fc..c0d0296e7a00 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.c
+++ b/drivers/infiniband/hw/nes/nes_verbs.c
@@ -2341,9 +2341,9 @@ static struct ib_mr *nes_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
2341 nes_debug(NES_DBG_MR, "User base = 0x%lX, Virt base = 0x%lX, length = %u," 2341 nes_debug(NES_DBG_MR, "User base = 0x%lX, Virt base = 0x%lX, length = %u,"
2342 " offset = %u, page size = %u.\n", 2342 " offset = %u, page size = %u.\n",
2343 (unsigned long int)start, (unsigned long int)virt, (u32)length, 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 if (ib_copy_from_udata(&req, udata, sizeof(req))) { 2348 if (ib_copy_from_udata(&req, udata, sizeof(req))) {
2349 ib_umem_release(region); 2349 ib_umem_release(region);
@@ -2408,7 +2408,7 @@ static struct ib_mr *nes_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
2408 region_length -= skip_pages << 12; 2408 region_length -= skip_pages << 12;
2409 for (page_index = skip_pages; page_index < chunk_pages; page_index++) { 2409 for (page_index = skip_pages; page_index < chunk_pages; page_index++) {
2410 skip_pages = 0; 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 goto enough_pages; 2412 goto enough_pages;
2413 if ((page_count&0x01FF) == 0) { 2413 if ((page_count&0x01FF) == 0) {
2414 if (page_count >= 1024 * 512) { 2414 if (page_count >= 1024 * 512) {
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
index 4c68305ee781..b48fd01f34d2 100644
--- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
@@ -805,7 +805,7 @@ struct ib_mr *ocrdma_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len,
805 goto umem_err; 805 goto umem_err;
806 806
807 mr->hwmr.pbe_size = mr->umem->page_size; 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 mr->hwmr.va = usr_addr; 809 mr->hwmr.va = usr_addr;
810 mr->hwmr.len = len; 810 mr->hwmr.len = len;
811 mr->hwmr.remote_wr = (acc & IB_ACCESS_REMOTE_WRITE) ? 1 : 0; 811 mr->hwmr.remote_wr = (acc & IB_ACCESS_REMOTE_WRITE) ? 1 : 0;
diff --git a/drivers/infiniband/hw/qib/qib_mr.c b/drivers/infiniband/hw/qib/qib_mr.c
index 9bbb55347cc1..a77fb4fb14e4 100644
--- a/drivers/infiniband/hw/qib/qib_mr.c
+++ b/drivers/infiniband/hw/qib/qib_mr.c
@@ -258,7 +258,7 @@ struct ib_mr *qib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
258 mr->mr.user_base = start; 258 mr->mr.user_base = start;
259 mr->mr.iova = virt_addr; 259 mr->mr.iova = virt_addr;
260 mr->mr.length = length; 260 mr->mr.length = length;
261 mr->mr.offset = umem->offset; 261 mr->mr.offset = ib_umem_offset(umem);
262 mr->mr.access_flags = mr_access_flags; 262 mr->mr.access_flags = mr_access_flags;
263 mr->umem = umem; 263 mr->umem = umem;
264 264
diff --git a/include/rdma/ib_umem.h b/include/rdma/ib_umem.h
index a2bf41e0bde9..7ed6d4ff58dc 100644
--- a/include/rdma/ib_umem.h
+++ b/include/rdma/ib_umem.h
@@ -42,7 +42,7 @@ struct ib_ucontext;
42struct ib_umem { 42struct ib_umem {
43 struct ib_ucontext *context; 43 struct ib_ucontext *context;
44 size_t length; 44 size_t length;
45 int offset; 45 unsigned long address;
46 int page_size; 46 int page_size;
47 int writable; 47 int writable;
48 int hugetlb; 48 int hugetlb;
@@ -55,6 +55,29 @@ struct ib_umem {
55 int npages; 55 int npages;
56}; 56};
57 57
58/* Returns the offset of the umem start relative to the first page. */
59static 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. */
65static 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. */
71static inline unsigned long ib_umem_end(struct ib_umem *umem)
72{
73 return PAGE_ALIGN(umem->address + umem->length);
74}
75
76static 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}
80
58#ifdef CONFIG_INFINIBAND_USER_MEM 81#ifdef CONFIG_INFINIBAND_USER_MEM
59 82
60struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr, 83struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,