Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8e907ed4 authored by Lidong Chen's avatar Lidong Chen Committed by Jason Gunthorpe
Browse files

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: 87773dd5 ("IB: ib_umem_release() should decrement mm->pinned_vm from ib_umem_get")
Signed-off-by: default avatarLidong Chen <lidongchen@tencent.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent 3d691910
Loading
Loading
Loading
Loading
+1 −6
Original line number Diff line number Diff line
@@ -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 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
	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);
+0 −1
Original line number Diff line number Diff line
@@ -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;