All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chaitanya Kulkarni <chaitanyak@nvidia.com>
To: Kanchan Joshi <joshi.k@samsung.com>
Cc: "io-uring@vger.kernel.org" <io-uring@vger.kernel.org>,
	"axboe@kernel.dk" <axboe@kernel.dk>,
	"asml.silence@gmail.com" <asml.silence@gmail.com>,
	"kbusch@kernel.org" <kbusch@kernel.org>,
	"hch@lst.de" <hch@lst.de>,
	"linux-nvme@lists.infradead.org" <linux-nvme@lists.infradead.org>,
	"linux-block@vger.kernel.org" <linux-block@vger.kernel.org>,
	"gost.dev@samsung.com" <gost.dev@samsung.com>,
	Anuj Gupta <anuj20.g@samsung.com>
Subject: Re: [PATCH for-next v5 3/4] block: add helper to map bvec iterator for passthrough
Date: Wed, 7 Sep 2022 15:32:26 +0000	[thread overview]
Message-ID: <81816f51-e720-4f9c-472f-17882f70b4f9@nvidia.com> (raw)
In-Reply-To: <20220906062721.62630-4-joshi.k@samsung.com>

On 9/5/22 23:27, Kanchan Joshi wrote:
> Add blk_rq_map_user_bvec which maps the bvec iterator into a bio and
> places that into the request. This helper will be used in nvme for
> uring-passthrough with fixed-buffer.
> While at it, create another helper bio_map_get to reduce the code
> duplication.
> 
> Signed-off-by: Kanchan Joshi <joshi.k@samsung.com>
> Signed-off-by: Anuj Gupta <anuj20.g@samsung.com>
> ---
>   block/blk-map.c        | 94 +++++++++++++++++++++++++++++++++++++-----
>   include/linux/blk-mq.h |  1 +
>   2 files changed, 85 insertions(+), 10 deletions(-)
> 
> diff --git a/block/blk-map.c b/block/blk-map.c
> index f3768876d618..e2f268167342 100644
> --- a/block/blk-map.c
> +++ b/block/blk-map.c
> @@ -241,17 +241,10 @@ static void bio_map_put(struct bio *bio)
>   	}
>   }
>   
> -static int bio_map_user_iov(struct request *rq, struct iov_iter *iter,
> +static struct bio *bio_map_get(struct request *rq, unsigned int nr_vecs,
>   		gfp_t gfp_mask)
>   {
> -	unsigned int max_sectors = queue_max_hw_sectors(rq->q);
> -	unsigned int nr_vecs = iov_iter_npages(iter, BIO_MAX_VECS);
>   	struct bio *bio;
> -	int ret;
> -	int j;
> -
> -	if (!iov_iter_count(iter))
> -		return -EINVAL;
>   
>   	if (rq->cmd_flags & REQ_POLLED) {
>   		blk_opf_t opf = rq->cmd_flags | REQ_ALLOC_CACHE;
> @@ -259,13 +252,31 @@ static int bio_map_user_iov(struct request *rq, struct iov_iter *iter,
>   		bio = bio_alloc_bioset(NULL, nr_vecs, opf, gfp_mask,
>   					&fs_bio_set);
>   		if (!bio)
> -			return -ENOMEM;
> +			return NULL;
>   	} else {
>   		bio = bio_kmalloc(nr_vecs, gfp_mask);
>   		if (!bio)
> -			return -ENOMEM;
> +			return NULL;
>   		bio_init(bio, NULL, bio->bi_inline_vecs, nr_vecs, req_op(rq));
>   	}
> +	return bio;
> +}
> +
> +static int bio_map_user_iov(struct request *rq, struct iov_iter *iter,
> +		gfp_t gfp_mask)
> +{
> +	unsigned int max_sectors = queue_max_hw_sectors(rq->q);
> +	unsigned int nr_vecs = iov_iter_npages(iter, BIO_MAX_VECS);
> +	struct bio *bio;
> +	int ret;
> +	int j;
> +
> +	if (!iov_iter_count(iter))
> +		return -EINVAL;
> +
> +	bio = bio_map_get(rq, nr_vecs, gfp_mask);
> +	if (bio == NULL)
> +		return -ENOMEM;
>   
>   	while (iov_iter_count(iter)) {
>   		struct page **pages, *stack_pages[UIO_FASTIOV];
> @@ -612,6 +623,69 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq,
>   }
>   EXPORT_SYMBOL(blk_rq_map_user);
>   
> +/* Prepare bio for passthrough IO given an existing bvec iter */
> +int blk_rq_map_user_bvec(struct request *rq, struct iov_iter *iter)
> +{
> +	struct request_queue *q = rq->q;
> +	size_t iter_count, nr_segs;
> +	struct bio *bio;
> +	struct bio_vec *bv, *bvec_arr, *bvprvp = NULL;
> +	struct queue_limits *lim = &q->limits;
> +	unsigned int nsegs = 0, bytes = 0;
> +	int ret, i;
> +

consider this (untested), it also sets the variable i data type same
as it comparison variable in nr_segs the loop i.e. size_t :-

+       struct bio_vec *bv, *bvec_arr, *bvprvp = NULL;
+       struct request_queue *q = rq->q;
+       struct queue_limits *lim = &q->limits;
+       unsigned int nsegs = 0, bytes = 0;
+       size_t iter_count, nr_segs, i;
+       struct bio *bio;
+       int ret;


> +	iter_count = iov_iter_count(iter);
> +	nr_segs = iter->nr_segs;
> +
> +	if (!iter_count || (iter_count >> 9) > queue_max_hw_sectors(q))
> +		return -EINVAL;

can we remove braces for iter_count >> 9 without impacting the intended
functionality?

> +	if (nr_segs > queue_max_segments(q))
> +		return -EINVAL;
> +
> +	/* no iovecs to alloc, as we already have a BVEC iterator */
> +	bio = bio_map_get(rq, 0, GFP_KERNEL);
> +	if (bio == NULL)
> +		return -ENOMEM;
> +
> +	bio_iov_bvec_set(bio, iter);
> +	blk_rq_bio_prep(rq, bio, nr_segs);
> +
> +	/* loop to perform a bunch of sanity checks */
> +	bvec_arr = (struct bio_vec *)iter->bvec;
> +	for (i = 0; i < nr_segs; i++) {
> +		bv = &bvec_arr[i];

I'd just call bvecs instead of bvec_arr, just personal preference.

> +		/*
> +		 * If the queue doesn't support SG gaps and adding this
> +		 * offset would create a gap, disallow it.
> +		 */
> +		if (bvprvp && bvec_gap_to_prev(lim, bvprvp, bv->bv_offset)) {
> +			ret = -EINVAL;
> +			goto out_free;
> +		}
> +
> +		/* check full condition */
> +		if (nsegs >= nr_segs || bytes > UINT_MAX - bv->bv_len) {
> +			ret = -EINVAL;
> +			goto out_free;
> +		}
> +
> +		if (bytes + bv->bv_len <= iter_count &&
> +				bv->bv_offset + bv->bv_len <= PAGE_SIZE) {
> +			nsegs++;
> +			bytes += bv->bv_len;
> +		} else {
> +			ret = -EINVAL;
> +			goto out_free;

you are only calling goto out_free; from loop with ret = -EINVAL.
you can remove redundant ret = -EINVAL assignment in the loop and
call return -EINVAL from the out_free: label instead return ret.
That will also allow us to remove braces in the loop.

This will also allow us to remove the ret variable on the
since I guess we are in the fast path.

> +		}
> +		bvprvp = bv;
> +	}
> +	return 0;
> +out_free:
> +	bio_map_put(bio);
> +	return ret;
> +}
> +EXPORT_SYMBOL(blk_rq_map_user_bvec);

why not use EXPORT_SYMBOL_GPL() for new addition?

I'm aware that blk-map.c only uses EXPORT_SYMBOL().

> +
>   /**
>    * blk_rq_unmap_user - unmap a request with user data
>    * @bio:	       start of bio list
> diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
> index b43c81d91892..83bef362f0f9 100644
> --- a/include/linux/blk-mq.h
> +++ b/include/linux/blk-mq.h
> @@ -970,6 +970,7 @@ struct rq_map_data {
>   	bool from_user;
>   };
>   
> +int blk_rq_map_user_bvec(struct request *rq, struct iov_iter *iter);
>   int blk_rq_map_user(struct request_queue *, struct request *,
>   		struct rq_map_data *, void __user *, unsigned long, gfp_t);
>   int blk_rq_map_user_iov(struct request_queue *, struct request *,


  reply	other threads:[~2022-09-07 15:32 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CGME20220906063719epcas5p3157e79583a5412a3be81f3d96f8aaadd@epcas5p3.samsung.com>
2022-09-06  6:27 ` [PATCH for-next v5 0/4] fixed-buffer for uring-cmd/passthru Kanchan Joshi
2022-09-06  6:27   ` [PATCH for-next v5 1/4] io_uring: introduce io_uring_cmd_import_fixed Kanchan Joshi
2022-09-06  6:27   ` [PATCH for-next v5 2/4] io_uring: introduce fixed buffer support for io_uring_cmd Kanchan Joshi
2022-09-06  6:27   ` [PATCH for-next v5 3/4] block: add helper to map bvec iterator for passthrough Kanchan Joshi
2022-09-07 15:32     ` Chaitanya Kulkarni [this message]
2022-09-08 10:52       ` Kanchan Joshi
2022-09-08 14:46         ` Jens Axboe
2022-09-08 15:11         ` Pankaj Raghav
2022-09-06  6:27   ` [PATCH for-next v5 4/4] nvme: wire up fixed buffer support for nvme passthrough Kanchan Joshi
2022-09-07 14:51     ` Chaitanya Kulkarni
2022-09-08 10:47       ` Kanchan Joshi
2022-09-08 14:50         ` Jens Axboe

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=81816f51-e720-4f9c-472f-17882f70b4f9@nvidia.com \
    --to=chaitanyak@nvidia.com \
    --cc=anuj20.g@samsung.com \
    --cc=asml.silence@gmail.com \
    --cc=axboe@kernel.dk \
    --cc=gost.dev@samsung.com \
    --cc=hch@lst.de \
    --cc=io-uring@vger.kernel.org \
    --cc=joshi.k@samsung.com \
    --cc=kbusch@kernel.org \
    --cc=linux-block@vger.kernel.org \
    --cc=linux-nvme@lists.infradead.org \
    /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.