aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLidong Chen <jemmy858585@gmail.com>2018-05-08 04:50:16 -0400
committerJason Gunthorpe <jgg@mellanox.com>2018-05-15 19:09:10 -0400
commit8e907ed4882714fd13cfe670681fc6cb5284c780 (patch)
tree5ce4bf10cbe8129f41020043768d3958eebb2eff /drivers
parent3d69191086fc87f202c79eb8873b9c82c2bb065a (diff)
IB/umem: Use the correct mm during ib_umem_release
User-space may invoke ibv_reg_mr and ibv_dereg_mr in different threads. If ibv_dereg_mr is called after the thread which invoked ibv_reg_mr has exited, get_pid_task will return NULL and ib_umem_release will not decrease mm->pinned_vm. Instead of using threads to locate the mm, use the overall tgid from the ib_ucontext struct instead. This matches the behavior of ODP and disassociate in handling the mm of the process that called ibv_reg_mr. Cc: <stable@vger.kernel.org> Fixes: 87773dd56d54 ("IB: ib_umem_release() should decrement mm->pinned_vm from ib_umem_get") Signed-off-by: Lidong Chen <lidongchen@tencent.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/infiniband/core/umem.c7
1 files changed, 1 insertions, 6 deletions
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
index 9a4e899d94b3..2b6c9b516070 100644
--- a/drivers/infiniband/core/umem.c
+++ b/drivers/infiniband/core/umem.c
@@ -119,7 +119,6 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
119 umem->length = size; 119 umem->length = size;
120 umem->address = addr; 120 umem->address = addr;
121 umem->page_shift = PAGE_SHIFT; 121 umem->page_shift = PAGE_SHIFT;
122 umem->pid = get_task_pid(current, PIDTYPE_PID);
123 /* 122 /*
124 * We ask for writable memory if any of the following 123 * We ask for writable memory if any of the following
125 * access flags are set. "Local write" and "remote write" 124 * access flags are set. "Local write" and "remote write"
@@ -132,7 +131,6 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
132 IB_ACCESS_REMOTE_ATOMIC | IB_ACCESS_MW_BIND)); 131 IB_ACCESS_REMOTE_ATOMIC | IB_ACCESS_MW_BIND));
133 132
134 if (access & IB_ACCESS_ON_DEMAND) { 133 if (access & IB_ACCESS_ON_DEMAND) {
135 put_pid(umem->pid);
136 ret = ib_umem_odp_get(context, umem, access); 134 ret = ib_umem_odp_get(context, umem, access);
137 if (ret) { 135 if (ret) {
138 kfree(umem); 136 kfree(umem);
@@ -148,7 +146,6 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
148 146
149 page_list = (struct page **) __get_free_page(GFP_KERNEL); 147 page_list = (struct page **) __get_free_page(GFP_KERNEL);
150 if (!page_list) { 148 if (!page_list) {
151 put_pid(umem->pid);
152 kfree(umem); 149 kfree(umem);
153 return ERR_PTR(-ENOMEM); 150 return ERR_PTR(-ENOMEM);
154 } 151 }
@@ -231,7 +228,6 @@ out:
231 if (ret < 0) { 228 if (ret < 0) {
232 if (need_release) 229 if (need_release)
233 __ib_umem_release(context->device, umem, 0); 230 __ib_umem_release(context->device, umem, 0);
234 put_pid(umem->pid);
235 kfree(umem); 231 kfree(umem);
236 } else 232 } else
237 current->mm->pinned_vm = locked; 233 current->mm->pinned_vm = locked;
@@ -274,8 +270,7 @@ void ib_umem_release(struct ib_umem *umem)
274 270
275 __ib_umem_release(umem->context->device, umem, 1); 271 __ib_umem_release(umem->context->device, umem, 1);
276 272
277 task = get_pid_task(umem->pid, PIDTYPE_PID); 273 task = get_pid_task(umem->context->tgid, PIDTYPE_PID);
278 put_pid(umem->pid);
279 if (!task) 274 if (!task)
280 goto out; 275 goto out;
281 mm = get_task_mm(task); 276 mm = get_task_mm(task);