Re: [PATCH 08/17] nvme: enable passthrough with fixed-buffer

Kanchan Joshi
2022-03-14T13:10:13Z

On Mon, Mar 14, 2022 at 5:49 PM Ming Lei <ming.lei@redhat.com> wrote:
>
> On Tue, Mar 08, 2022 at 08:50:56PM +0530, Kanchan Joshi wrote:
> > From: Anuj Gupta <anuj20.g@samsung.com>
> >
> > Add support to carry out passthrough command with pre-mapped buffers.
> >
> > Signed-off-by: Anuj Gupta <anuj20.g@samsung.com>
> > Signed-off-by: Kanchan Joshi <joshi.k@samsung.com>
> > ---
> > block/blk-map.c | 45 +++++++++++++++++++++++++++++++++++++++
> > drivers/nvme/host/ioctl.c | 27 ++++++++++++++---------
> > include/linux/blk-mq.h | 2 ++
> > 3 files changed, 64 insertions(+), 10 deletions(-)
> >
> > diff --git a/block/blk-map.c b/block/blk-map.c
> > index 4526adde0156..027e8216e313 100644
> > --- a/block/blk-map.c
> > +++ b/block/blk-map.c
> > @@ -8,6 +8,7 @@
> > #include <linux/bio.h>
> > #include <linux/blkdev.h>
> > #include <linux/uio.h>
> > +#include <linux/io_uring.h>
> >
> > #include "blk.h"
> >
> > @@ -577,6 +578,50 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq,
> > }
> > EXPORT_SYMBOL(blk_rq_map_user);
> >
> > +/* Unlike blk_rq_map_user () this is only for fixed-buffer async passthrough. */
> > +int blk_rq_map_user_fixedb(struct request_queue *q, struct request *rq,
> > + u64 ubuf, unsigned long len, gfp_t gfp_mask,
> > + struct io_uring_cmd *ioucmd)
> > +{
> > + struct iov_iter iter;
> > + size_t iter_count, nr_segs;
> > + struct bio *bio;
> > + int ret;
> > +
> > + /*
> > + * Talk to io_uring to obtain BVEC iterator for the buffer.
> > + * And use that iterator to form bio/request.
> > + */
> > + ret = io_uring_cmd_import_fixed(ubuf, len, rq_data_dir(rq), &iter,
> > + ioucmd);
> > + if (unlikely(ret < 0))
> > + return 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;
> > + if (nr_segs > queue_max_segments(q))
> > + return -EINVAL;
> > + /* no iovecs to alloc, as we already have a BVEC iterator */
> > + bio = bio_alloc(gfp_mask, 0);
> > + if (!bio)
> > + return -ENOMEM;
> > +
> > + ret = bio_iov_iter_get_pages(bio, &iter);
>
> Here bio_iov_iter_get_pages() may not work as expected since the code
> needs to check queue limit before adding page to bio and we don't run
> split for passthrough bio. __bio_iov_append_get_pages() may be generalized
> for covering this case.

Yes. That may just be the right thing to do. Thanks for the suggestion.

--
Kanchan