All of lore.kernel.org
 help / color / mirror / Atom feed
From: Leon Romanovsky <leon@kernel.org>
To: Yamin Friedman <yaminf@mellanox.com>
Cc: Jason Gunthorpe <jgg@mellanox.com>,
	Sagi Grimberg <sagi@grimberg.me>, Christoph Hellwig <hch@lst.de>,
	linux-rdma@vger.kernel.org
Subject: Re: [PATCH 1/4] infiniband/core: Add protection for shared CQs used by ULPs
Date: Mon, 11 May 2020 07:37:53 +0300	[thread overview]
Message-ID: <20200511043753.GA356445@unreal> (raw)
In-Reply-To: <1589122557-88996-2-git-send-email-yaminf@mellanox.com>

On Sun, May 10, 2020 at 05:55:54PM +0300, Yamin Friedman wrote:
> A pre-step for adding shared CQs. Add the infra-structure to prevent
> shared CQ users from altering the CQ configurations. For now all cqs are
> marked as private (non-shared). The core driver should use the new force
> functions to perform resize/destroy/moderation changes that are not
> allowed for users of shared CQs.
>
> Signed-off-by: Yamin Friedman <yaminf@mellanox.com>
> Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com>
> ---
>  drivers/infiniband/core/cq.c    | 25 ++++++++++++++++++-------
>  drivers/infiniband/core/verbs.c | 37 ++++++++++++++++++++++++++++++++++---
>  include/rdma/ib_verbs.h         | 20 +++++++++++++++++++-
>  3 files changed, 71 insertions(+), 11 deletions(-)

infiniband/core -> RDMA/core

>
> diff --git a/drivers/infiniband/core/cq.c b/drivers/infiniband/core/cq.c
> index 4f25b24..443a9cd 100644
> --- a/drivers/infiniband/core/cq.c
> +++ b/drivers/infiniband/core/cq.c
> @@ -37,6 +37,7 @@ static void ib_cq_rdma_dim_work(struct work_struct *w)
>  {
>  	struct dim *dim = container_of(w, struct dim, work);
>  	struct ib_cq *cq = dim->priv;
> +	int ret;
>
>  	u16 usec = rdma_dim_prof[dim->profile_ix].usec;
>  	u16 comps = rdma_dim_prof[dim->profile_ix].comps;
> @@ -44,7 +45,10 @@ static void ib_cq_rdma_dim_work(struct work_struct *w)
>  	dim->state = DIM_START_MEASURE;
>
>  	trace_cq_modify(cq, comps, usec);
> -	cq->device->ops.modify_cq(cq, comps, usec);
> +	ret = rdma_set_cq_moderation_force(cq, comps, usec);
> +	if (ret)
> +		WARN_ONCE(1, "Failed set moderation for CQ 0x%p\n", cq);

First WARN_ONCE(ret, ...), second no to pointer address print and third
this dump stack won't help, because CQ moderation will fail for many
reasons unrelated to the caller.

> +
>  }
>
>  static void rdma_dim_init(struct ib_cq *cq)
> @@ -218,6 +222,7 @@ struct ib_cq *__ib_alloc_cq_user(struct ib_device *dev, void *private,
>  	cq->cq_context = private;
>  	cq->poll_ctx = poll_ctx;
>  	atomic_set(&cq->usecnt, 0);
> +	cq->cq_type = IB_CQ_PRIVATE;

I would say it should be opposite, default is not shared CQ and only
pool sets something specific to mark that it is shared.

>
>  	cq->wc = kmalloc_array(IB_POLL_BATCH, sizeof(*cq->wc), GFP_KERNEL);
>  	if (!cq->wc)
> @@ -300,12 +305,7 @@ struct ib_cq *__ib_alloc_cq_any(struct ib_device *dev, void *private,
>  }
>  EXPORT_SYMBOL(__ib_alloc_cq_any);
>
> -/**
> - * ib_free_cq_user - free a completion queue
> - * @cq:		completion queue to free.
> - * @udata:	User data or NULL for kernel object
> - */
> -void ib_free_cq_user(struct ib_cq *cq, struct ib_udata *udata)
> +static void _ib_free_cq_user(struct ib_cq *cq, struct ib_udata *udata)
>  {
>  	if (WARN_ON_ONCE(atomic_read(&cq->usecnt)))
>  		return;
> @@ -333,4 +333,15 @@ void ib_free_cq_user(struct ib_cq *cq, struct ib_udata *udata)
>  	kfree(cq->wc);
>  	kfree(cq);
>  }
> +
> +/**
> + * ib_free_cq_user - free a completion queue
> + * @cq:		completion queue to free.
> + * @udata:	User data or NULL for kernel object
> + */
> +void ib_free_cq_user(struct ib_cq *cq, struct ib_udata *udata)
> +{
> +	if (!WARN_ON_ONCE(cq->cq_type != IB_CQ_PRIVATE))
> +		_ib_free_cq_user(cq, udata);
> +}

It is not preferable kernel style - not on WARN_ON_ONCE() and do
something later.

>  EXPORT_SYMBOL(ib_free_cq_user);
> diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
> index bf0249f..39c012f 100644
> --- a/drivers/infiniband/core/verbs.c
> +++ b/drivers/infiniband/core/verbs.c
> @@ -1988,15 +1988,29 @@ struct ib_cq *__ib_create_cq(struct ib_device *device,
>  }
>  EXPORT_SYMBOL(__ib_create_cq);
>
> -int rdma_set_cq_moderation(struct ib_cq *cq, u16 cq_count, u16 cq_period)
> +static int _rdma_set_cq_moderation(struct ib_cq *cq, u16 cq_count,
> +				   u16 cq_period)
>  {
>  	return cq->device->ops.modify_cq ?
>  		cq->device->ops.modify_cq(cq, cq_count,
>  					  cq_period) : -EOPNOTSUPP;
>  }
> +
> +int rdma_set_cq_moderation(struct ib_cq *cq, u16 cq_count, u16 cq_period)
> +{
> +	if (WARN_ON_ONCE(cq->cq_type != IB_CQ_PRIVATE))
> +		return -EOPNOTSUPP;
> +	else
> +		return _rdma_set_cq_moderation(cq, cq_count, cq_period);
> +}
>  EXPORT_SYMBOL(rdma_set_cq_moderation);
>
> -int ib_destroy_cq_user(struct ib_cq *cq, struct ib_udata *udata)
> +int rdma_set_cq_moderation_force(struct ib_cq *cq, u16 cq_count, u16 cq_period)
> +{
> +	return _rdma_set_cq_moderation(cq, cq_count, cq_period);
> +}

All these one liners makes no sense, the call to
_rdma_set_cq_moderation() in this function and above is exactly the
same. It means there is no need in specific function.

> +
> +static int _ib_destroy_cq_user(struct ib_cq *cq, struct ib_udata *udata)
>  {
>  	if (atomic_read(&cq->usecnt))
>  		return -EBUSY;
> @@ -2004,15 +2018,32 @@ int ib_destroy_cq_user(struct ib_cq *cq, struct ib_udata *udata)
>  	rdma_restrack_del(&cq->res);
>  	cq->device->ops.destroy_cq(cq, udata);
>  	kfree(cq);
> +

Not relevant

>  	return 0;
>  }
> +
> +int ib_destroy_cq_user(struct ib_cq *cq, struct ib_udata *udata)
> +{
> +	if (WARN_ON_ONCE(cq->cq_type != IB_CQ_PRIVATE))
> +		return -EOPNOTSUPP;
> +	else
> +		return _ib_destroy_cq_user(cq, udata);
> +}
>  EXPORT_SYMBOL(ib_destroy_cq_user);

I would expect symmetric API, you can call to create_cq_user for your
pool, but can't call to destroy_cq_user, am I right?


>
> -int ib_resize_cq(struct ib_cq *cq, int cqe)
> +static int _ib_resize_cq(struct ib_cq *cq, int cqe)
>  {
>  	return cq->device->ops.resize_cq ?
>  		cq->device->ops.resize_cq(cq, cqe, NULL) : -EOPNOTSUPP;
>  }
> +
> +int ib_resize_cq(struct ib_cq *cq, int cqe)
> +{
> +	if (WARN_ON_ONCE(cq->cq_type != IB_CQ_PRIVATE))
> +		return -EOPNOTSUPP;
> +	else
> +		return _ib_resize_cq(cq, cqe);
> +}
>  EXPORT_SYMBOL(ib_resize_cq);


It is not kernel style and probably dump_stack is not needed too.

>
>  /* Memory regions */
> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
> index 4c488ca..c889415 100644
> --- a/include/rdma/ib_verbs.h
> +++ b/include/rdma/ib_verbs.h
> @@ -1557,6 +1557,10 @@ enum ib_poll_context {
>  	IB_POLL_UNBOUND_WORKQUEUE, /* poll from unbound workqueue */
>  };
>
> +enum ib_cq_type {
> +	IB_CQ_PRIVATE,	/* CQ will be used by only one user */
> +};

Do you see another CQ types? If not it should not be a type but boolean.
If yes, PRIVATE is not really type but property.

> +
>  struct ib_cq {
>  	struct ib_device       *device;
>  	struct ib_ucq_object   *uobject;
> @@ -1582,6 +1586,7 @@ struct ib_cq {
>  	 * Implementation details of the RDMA core, don't use in drivers:
>  	 */
>  	struct rdma_restrack_entry res;
> +	enum ib_cq_type cq_type;
>  };
>
>  struct ib_srq {
> @@ -3832,6 +3837,7 @@ static inline struct ib_cq *ib_alloc_cq_any(struct ib_device *dev,
>   * @cq: The CQ to free
>   *
>   * NOTE: for user cq use ib_free_cq_user with valid udata!
> + * NOTE: this will fail for shared cqs
>   */
>  static inline void ib_free_cq(struct ib_cq *cq)
>  {
> @@ -3881,7 +3887,19 @@ struct ib_cq *__ib_create_cq(struct ib_device *device,
>  int rdma_set_cq_moderation(struct ib_cq *cq, u16 cq_count, u16 cq_period);
>
>  /**
> - * ib_destroy_cq_user - Destroys the specified CQ.
> + * rdma_set_cq_moderation_force - Modifies moderation params of the CQ.
> + * Meant for use in core driver to work for shared CQs.
> + * @cq: The CQ to modify.
> + * @cq_count: number of CQEs that will trigger an event
> + * @cq_period: max period of time in usec before triggering an event
> + *
> + */
> +int rdma_set_cq_moderation_force(struct ib_cq *cq, u16 cq_count,
> +				 u16 cq_period);
> +
> +/**
> + * ib_destroy_cq_user - Destroys the specified CQ. If the CQ is not
> + * PRIVATE this function will fail.

It is not only fail, but print huge dump_stack.

>   * @cq: The CQ to destroy.
>   * @udata: Valid user data or NULL for kernel objects
>   */
> --
> 1.8.3.1
>

  reply	other threads:[~2020-05-11  4:38 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-10 14:55 [PATCH 0/4] Introducing RDMA shared CQ pool Yamin Friedman
2020-05-10 14:55 ` [PATCH 1/4] infiniband/core: Add protection for shared CQs used by ULPs Yamin Friedman
2020-05-11  4:37   ` Leon Romanovsky [this message]
2020-05-11  8:39     ` Sagi Grimberg
2020-05-11 11:52       ` Yamin Friedman
2020-05-11 11:59     ` Yamin Friedman
2020-05-11 16:45       ` Leon Romanovsky
2020-05-10 14:55 ` [PATCH 2/4] RDMA/core: Introduce shared CQ pool API Yamin Friedman
2020-05-11  5:07   ` Leon Romanovsky
2020-05-11 12:08     ` Yamin Friedman
2020-05-11 16:39       ` Leon Romanovsky
2020-05-12  7:00       ` Yamin Friedman
2020-05-12  8:08         ` Leon Romanovsky
2020-05-11  8:49   ` Sagi Grimberg
2020-05-11 12:03     ` Yamin Friedman
2020-05-12  6:55       ` Sagi Grimberg
2020-05-12  8:40         ` Yamin Friedman
2020-05-12  3:08   ` [RDMA/core] 7b491b3fb2: BUG:kernel_hang_in_test_stage kernel test robot
2020-05-12  3:08     ` kernel test robot
2020-05-10 14:55 ` [PATCH 3/4] nvme-rdma: use new shared CQ mechanism Yamin Friedman
2020-05-11  8:50   ` Sagi Grimberg
2020-05-11 16:29   ` Max Gurtovoy
2020-05-10 14:55 ` [PATCH 4/4] nvmet-rdma: " Yamin Friedman
2020-05-11  8:50   ` Sagi Grimberg
2020-05-10 15:04 ` [PATCH 0/4] Introducing RDMA shared CQ pool Gal Pressman
2020-05-10 15:17   ` Yamin Friedman
2020-05-11  8:34 ` Sagi Grimberg
2020-05-11 12:24   ` Yamin Friedman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200511043753.GA356445@unreal \
    --to=leon@kernel.org \
    --cc=hch@lst.de \
    --cc=jgg@mellanox.com \
    --cc=linux-rdma@vger.kernel.org \
    --cc=sagi@grimberg.me \
    --cc=yaminf@mellanox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.