On 11/20/23 3:40 PM, Keith Busch wrote: > From: Keith Busch <kbusch@xxxxxxxxxx> > > Passthrough commands that utilize metadata currently bounce the user > space buffer through the kernel. Add support for mapping user space > directly so that we can avoid this costly overhead. This is similiar to > how the normal bio data payload utilizes user addresses with > bio_map_user_iov(). > > If the user address can't directly be used for reasons like too many > segments or address unalignement, fallback to a copy of the user vec > while keeping the user address pinned for the IO duration so that it > can safely be copied on completion in any process context. > > Signed-off-by: Keith Busch <kbusch@xxxxxxxxxx> > --- > block/bio-integrity.c | 212 ++++++++++++++++++++++++++++++++++++++++++ > include/linux/bio.h | 12 +++ > 2 files changed, 224 insertions(+) > > diff --git a/block/bio-integrity.c b/block/bio-integrity.c > index ec8ac8cf6e1b9..b761058bfb92f 100644 > --- a/block/bio-integrity.c > +++ b/block/bio-integrity.c > @@ -91,6 +91,37 @@ struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio, > } > EXPORT_SYMBOL(bio_integrity_alloc); > > +static void bio_integrity_unmap_user(struct bio_integrity_payload *bip) > +{ > + bool dirty = bio_data_dir(bip->bip_bio) == READ; > + struct bvec_iter iter; > + struct bio_vec bv; > + > + if (bip->bip_flags & BIP_COPY_USER) { > + unsigned short nr_vecs = bip->bip_max_vcnt - 1; > + struct bio_vec *copy = bvec_virt(&bip->bip_vec[nr_vecs]); > + size_t bytes = bip->bip_iter.bi_size; > + void *buf = bvec_virt(bip->bip_vec); > + > + if (dirty) { > + struct iov_iter iter; > + > + iov_iter_bvec(&iter, ITER_DEST, copy, nr_vecs, bytes); > + WARN_ON_ONCE(copy_to_iter(buf, bytes, &iter) != bytes); > + } Minor nit, but I don't like hiding functions with side effects inside potentially debug statements. Would be better to do: ret = copy_to_iter(buf, bytes, &iter); WARN_ON_ONCE(ret != bytes); which is also easier to read, imho. Apart from that, looks good to me. -- Jens Axboe