On 01/16/2019 05:12 PM, Christoph Hellwig wrote:
When a host driver sets a maximum segment size we should not only
propagate that setting to the block layer, which can merge segments,
but also to the DMA mapping layer which can merge segments as well.

Fixes: 50c2e9107f ("scsi: introduce a max_segment_size host_template 
parameters")
Signed-off-by: Christoph Hellwig <h...@lst.de>
---
  drivers/ata/pata_macio.c     |  9 ++++-----
  drivers/ata/sata_inic162x.c  | 22 +++++++++-------------
  drivers/firewire/sbp2.c      |  5 +----
  drivers/scsi/aacraid/linit.c |  9 ++++-----
  drivers/scsi/scsi_lib.c      |  4 ++--
  5 files changed, 20 insertions(+), 29 deletions(-)

diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c
index 09b845e90114..a785ffd5af89 100644
--- a/drivers/firewire/sbp2.c
+++ b/drivers/firewire/sbp2.c
@@ -1144,10 +1144,6 @@ static int sbp2_probe(struct fw_unit *unit, const struct 
ieee1394_device_id *id)
        if (device->is_local)
                return -ENODEV;

-       if (dma_get_max_seg_size(device->card->device) > SBP2_MAX_SEG_SIZE)
-               WARN_ON(dma_set_max_seg_size(device->card->device,
-                                            SBP2_MAX_SEG_SIZE));
-
        shost = scsi_host_alloc(&scsi_driver_template, sizeof(*tgt));
        if (shost == NULL)
                return -ENOMEM;
@@ -1610,6 +1606,7 @@ static struct scsi_host_template scsi_driver_template = {
        .eh_abort_handler       = sbp2_scsi_abort,
        .this_id                = -1,
        .sg_tablesize           = SG_ALL,
+       .max_segment_size       = SBP2_MAX_SEG_SIZE,
        .can_queue              = 1,
        .sdev_attrs             = sbp2_scsi_sysfs_attrs,
  };

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index b13cc9288ba0..6d65ac584eba 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1842,8 +1842,8 @@ void __scsi_init_queue(struct Scsi_Host *shost, struct 
request_queue *q)
        blk_queue_segment_boundary(q, shost->dma_boundary);
        dma_set_seg_boundary(dev, shost->dma_boundary);

-       blk_queue_max_segment_size(q,
-               min(shost->max_segment_size, dma_get_max_seg_size(dev)));
+       blk_queue_max_segment_size(q, shost->max_segment_size);
+       dma_set_max_seg_size(dev, shost->max_segment_size);

Zfcp can only have max_segment_size of one page (4kB). Officially announced through dev.dma_parms since v2.6.35 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/s390/scsi?id=683229845f1780b10041ee7a1043fc8f10061455.

With Martin's 5.0/scsi-fixes which includes your above patch, I now get 64kB instead of 4kB for the respective queue limit because __scsi_ini_queue overwrites the dma parameter:

[root@host:/sys/bus/ccw/drivers/zfcp/0.0.3c40/host5/rport-5:0-4/target5:0:4/5:0:4:10/block/sdi/queue](0)# cat max_segment_size
65536

To my surprise, I don't get IO errors with zfcp. Maybe my IO pattern does not cause too large segments to be created. I would have expected the FCP channel complaining rightly so if we pass segments larger than one page. Maybe the additional dma_boundary of pagesize-1 helped the too large max_segment_size to not become effective?

A quick attempt to adapt zfcp to your patch would be to set scsi_host_template.max_segment_size = ZFCP_QDIO_SBALE_LEN.

Ideas?

--
Mit freundlichen Gruessen / Kind regards
Steffen Maier

Linux on IBM Z Development

https://www.ibm.com/privacy/us/en/
IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats: Matthias Hartmann
Geschaeftsfuehrung: Dirk Wittkopp
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294

Reply via email to