diff options
author | Lidong Chen <jemmy858585@gmail.com> | 2018-05-08 04:50:16 -0400 |
---|---|---|
committer | Jason Gunthorpe <jgg@mellanox.com> | 2018-05-15 19:09:10 -0400 |
commit | 8e907ed4882714fd13cfe670681fc6cb5284c780 (patch) | |
tree | 5ce4bf10cbe8129f41020043768d3958eebb2eff /drivers | |
parent | 3d69191086fc87f202c79eb8873b9c82c2bb065a (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.c | 7 |
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); |