Re: [PATCH v13 43/45] sg: no_dxfer: move to/from kernel buffers

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

 



On 1/14/21 6:11 PM, Douglas Gilbert wrote:
On 2021-01-14 2:30 a.m., Hannes Reinecke wrote:
On 1/13/21 11:45 PM, Douglas Gilbert wrote:
When the NO_DXFER flag is use on a command/request, the data-in
and data-out buffers (if present) should not be ignored. Add
sg_rq_map_kern() function to handle this. Uses a single bio with
multiple bvec_s usually each holding multiple pages, if necessary.
The driver default element size is 32 KiB so if PAGE_SIZE is 4096
then get_order()==3 .

Signed-off-by: Douglas Gilbert <dgilbert@xxxxxxxxxxxx>
---
  drivers/scsi/sg.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++
  1 file changed, 59 insertions(+)

diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index a00f488ee5e2..ad97f0756a9c 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -2865,6 +2865,63 @@ exit_sg(void)
      idr_destroy(&sg_index_idr);
  }
+static struct bio *
+sg_mk_kern_bio(int bvec_cnt)
+{
+    struct bio *biop;
+
+    if (bvec_cnt > BIO_MAX_PAGES)
+        return NULL;
+    biop = bio_alloc(GFP_ATOMIC, bvec_cnt);
+    if (!biop)
+        return NULL;
+    biop->bi_end_io = bio_put;

Huh? That is the default action, is it not?
So why specify it separately?

I'll check. That code snippet is copied from NVMe which has equivalent
code: moving storage data to/from _kernel_ buffers. Later in the driver
rewrite, bios are re-used, so if any earlier path puts a different
value in biop->bi_end_io, I'm screwed without that line. So I assumed
the NVMe code did it for a good reason.

Re-used? Uh-oh.
But okay, then it kinda makes sense.

[ .. ]
Why do you need to do the additional mapping?

I don't understand this question.

And doens't the 'NO_DXFER' flag indicate that _no_ data should be transferred?

NO, it absolutely does not mean that! With indirect IO (i.e. the default) there
are two transfers, taking a READ operation is an example:
   1) transfer user data from the device (a LU) to the internal buffer allocated
       by the sg driver. LLD arranges that transfer.
   2) transfer that user data from the internal buffer to the user space as       indicated by the call to ioctl(SG_IO) or its alternatives. This transfer
       is driven by the sg driver using copy_to_user().

The SG_FLAG_NO_DXFER flag skips step 2) _not_ 1) .

The SG_FLAG_NO_DXFER flag has been in the sg driver since 1998. Sometime between
2010 and now that functionality was quietly dropped. Tony Battersby for one
seemed quite peeved when I told him that functionality had been silently
dropped.

Ah. Now that makes sense. Data transfer with not data transfer.
You should've said :-)

I'll have another look with that in mind.

Cheers,

Hannes
--
Dr. Hannes Reinecke                Kernel Storage Architect
hare@xxxxxxx                              +49 911 74053 688
SUSE Software Solutions GmbH, Maxfeldstr. 5, 90409 Nürnberg
HRB 36809 (AG Nürnberg), Geschäftsführer: Felix Imendörffer



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux