diff options
| author | Lidong Chen <jemmy858585@gmail.com> | 2018-05-08 16:50:16 +0800 | 
|---|---|---|
| committer | Jason Gunthorpe <jgg@mellanox.com> | 2018-05-15 17:09:10 -0600 | 
| commit | 8e907ed4882714fd13cfe670681fc6cb5284c780 (patch) | |
| tree | 5ce4bf10cbe8129f41020043768d3958eebb2eff | |
| 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>
| -rw-r--r-- | drivers/infiniband/core/umem.c | 7 | ||||
| -rw-r--r-- | include/rdma/ib_umem.h | 1 | 
2 files changed, 1 insertions, 7 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,  	umem->length     = size;  	umem->address    = addr;  	umem->page_shift = PAGE_SHIFT; -	umem->pid	 = get_task_pid(current, PIDTYPE_PID);  	/*  	 * We ask for writable memory if any of the following  	 * 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,  		 IB_ACCESS_REMOTE_ATOMIC | IB_ACCESS_MW_BIND));  	if (access & IB_ACCESS_ON_DEMAND) { -		put_pid(umem->pid);  		ret = ib_umem_odp_get(context, umem, access);  		if (ret) {  			kfree(umem); @@ -148,7 +146,6 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,  	page_list = (struct page **) __get_free_page(GFP_KERNEL);  	if (!page_list) { -		put_pid(umem->pid);  		kfree(umem);  		return ERR_PTR(-ENOMEM);  	} @@ -231,7 +228,6 @@ out:  	if (ret < 0) {  		if (need_release)  			__ib_umem_release(context->device, umem, 0); -		put_pid(umem->pid);  		kfree(umem);  	} else  		current->mm->pinned_vm = locked; @@ -274,8 +270,7 @@ void ib_umem_release(struct ib_umem *umem)  	__ib_umem_release(umem->context->device, umem, 1); -	task = get_pid_task(umem->pid, PIDTYPE_PID); -	put_pid(umem->pid); +	task = get_pid_task(umem->context->tgid, PIDTYPE_PID);  	if (!task)  		goto out;  	mm = get_task_mm(task); diff --git a/include/rdma/ib_umem.h b/include/rdma/ib_umem.h index 23159dd5be18..a1fd63871d17 100644 --- a/include/rdma/ib_umem.h +++ b/include/rdma/ib_umem.h @@ -48,7 +48,6 @@ struct ib_umem {  	int                     writable;  	int                     hugetlb;  	struct work_struct	work; -	struct pid             *pid;  	struct mm_struct       *mm;  	unsigned long		diff;  	struct ib_umem_odp     *odp_data;  | 
