Re: [PATCH for-next] iw_cxgb4: Fix qpid leak

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, May 15, 2019 at 04:01:13AM -0700, Nirranjan Kirubaharan wrote:
> In iw_cxgb4, sometimes scheduled freeing of QPs complete after
> completion of dealloc_ucontext(). So in use qpids stored in ucontext
> gets lost, causing qpid leak. Added changes in dealloc_ucontext(),
> to wait until completion of freeing of all QPs.
>
> Signed-off-by: Nirranjan Kirubaharan <nirranjan@xxxxxxxxxxx>
> Reviewed-by: Potnuri Bharat Teja <bharat@xxxxxxxxxxx>
> ---
>  drivers/infiniband/hw/cxgb4/device.c   | 3 +++
>  drivers/infiniband/hw/cxgb4/iw_cxgb4.h | 2 ++
>  drivers/infiniband/hw/cxgb4/provider.c | 6 +++++-
>  drivers/infiniband/hw/cxgb4/resource.c | 9 +++++++++
>  4 files changed, 19 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c
> index 4c0d925c5ff5..fad4ca247bc7 100644
> --- a/drivers/infiniband/hw/cxgb4/device.c
> +++ b/drivers/infiniband/hw/cxgb4/device.c
> @@ -775,6 +775,9 @@ void c4iw_init_dev_ucontext(struct c4iw_rdev *rdev,
>  	INIT_LIST_HEAD(&uctx->qpids);
>  	INIT_LIST_HEAD(&uctx->cqids);
>  	mutex_init(&uctx->lock);
> +	uctx->qid_count = 0;
> +	init_completion(&uctx->qid_rel_comp);
> +	complete(&uctx->qid_rel_comp);

This line doesn't make sense to me.

Thanks

>  }
>
>  /* Caller takes care of locking if needed */
> diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
> index 916ef982172e..768532e29538 100644
> --- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
> +++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
> @@ -110,6 +110,8 @@ struct c4iw_dev_ucontext {
>  	struct list_head cqids;
>  	struct mutex lock;
>  	struct kref kref;
> +	struct completion qid_rel_comp;
> +	u32 qid_count;
>  };
>
>  enum c4iw_rdev_flags {
> diff --git a/drivers/infiniband/hw/cxgb4/provider.c b/drivers/infiniband/hw/cxgb4/provider.c
> index 74b795642fca..bfd541c55c31 100644
> --- a/drivers/infiniband/hw/cxgb4/provider.c
> +++ b/drivers/infiniband/hw/cxgb4/provider.c
> @@ -64,12 +64,16 @@ static void c4iw_dealloc_ucontext(struct ib_ucontext *context)
>  	struct c4iw_dev *rhp;
>  	struct c4iw_mm_entry *mm, *tmp;
>
> -	pr_debug("context %p\n", context);
> +	pr_debug("context %p\n", &ucontext->uctx);
>  	rhp = to_c4iw_dev(ucontext->ibucontext.device);
>
>  	list_for_each_entry_safe(mm, tmp, &ucontext->mmaps, entry)
>  		kfree(mm);
> +
> +	wait_for_completion(&ucontext->uctx.qid_rel_comp);
> +
>  	c4iw_release_dev_ucontext(&rhp->rdev, &ucontext->uctx);
> +	pr_debug("context %p done\n", &ucontext->uctx);
>  }
>
>  static int c4iw_alloc_ucontext(struct ib_ucontext *ucontext,
> diff --git a/drivers/infiniband/hw/cxgb4/resource.c b/drivers/infiniband/hw/cxgb4/resource.c
> index 57ed26b3cc21..e9cc06f8a9ad 100644
> --- a/drivers/infiniband/hw/cxgb4/resource.c
> +++ b/drivers/infiniband/hw/cxgb4/resource.c
> @@ -224,6 +224,10 @@ u32 c4iw_get_qpid(struct c4iw_rdev *rdev, struct c4iw_dev_ucontext *uctx)
>  			list_add_tail(&entry->entry, &uctx->cqids);
>  		}
>  	}
> +	if (uctx->qid_count == 0)
> +		reinit_completion(&uctx->qid_rel_comp);
> +	uctx->qid_count++;
> +
>  out:
>  	mutex_unlock(&uctx->lock);
>  	pr_debug("qid 0x%x\n", qid);
> @@ -246,6 +250,11 @@ void c4iw_put_qpid(struct c4iw_rdev *rdev, u32 qid,
>  	entry->qid = qid;
>  	mutex_lock(&uctx->lock);
>  	list_add_tail(&entry->entry, &uctx->qpids);
> +
> +	uctx->qid_count--;
> +	if (uctx->qid_count == 0)
> +		complete(&uctx->qid_rel_comp);
> +
>  	mutex_unlock(&uctx->lock);
>  }
>
> --
> 1.8.3.1
>



[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux