From bb7d1283e6280acdfe0faf10e8b6ebd1f5970fed Mon Sep 17 00:00:00 2001 From: John Garry Date: Thu, 14 Jul 2022 19:15:26 +0800 Subject: scsi: core: cap shost max_sectors according to DMA limits only once The shost->max_sectors is repeatedly capped according to the host DMA mapping limit for each sdev in __scsi_init_queue(). This is unnecessary, so set only once when adding the host. Signed-off-by: John Garry Reviewed-by: Damien Le Moal Acked-by: Martin K. Petersen Signed-off-by: Christoph Hellwig --- drivers/scsi/hosts.c | 5 +++++ drivers/scsi/scsi_lib.c | 4 ---- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/scsi') diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 8352f90d997d..d04bd2c7c9f1 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -236,6 +236,11 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, shost->dma_dev = dma_dev; + if (dma_dev->dma_mask) { + shost->max_sectors = min_t(unsigned int, shost->max_sectors, + dma_max_mapping_size(dma_dev) >> SECTOR_SHIFT); + } + error = scsi_mq_setup_tags(shost); if (error) goto fail; diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 6ffc9e4258a8..6ce8acea322a 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1884,10 +1884,6 @@ void __scsi_init_queue(struct Scsi_Host *shost, struct request_queue *q) blk_queue_max_integrity_segments(q, shost->sg_prot_tablesize); } - if (dev->dma_mask) { - shost->max_sectors = min_t(unsigned int, shost->max_sectors, - dma_max_mapping_size(dev) >> SECTOR_SHIFT); - } blk_queue_max_hw_sectors(q, shost->max_sectors); blk_queue_segment_boundary(q, shost->dma_boundary); dma_set_seg_boundary(dev, shost->dma_boundary); -- cgit v1.2.3 From 608128d391fa5c95d515d2c198f40239016e1fcd Mon Sep 17 00:00:00 2001 From: John Garry Date: Thu, 14 Jul 2022 19:15:27 +0800 Subject: scsi: sd: allow max_sectors be capped at DMA optimal size limit Streaming DMA mappings may be considerably slower when mappings go through an IOMMU and the total mapping length is somewhat long. This is because the IOMMU IOVA code allocates and free an IOVA for each mapping, which may affect performance. New member Scsi_Host.opt_sectors is added, which is the optimal host max_sectors, and use this value to cap the request queue max_sectors when set. It could be considered to have request queues io_opt value initially set at Scsi_Host.opt_sectors in __scsi_init_queue(), but that is not really the purpose of io_opt. Finally, even though Scsi_Host.opt_sectors value should never be greater than the request queue max_hw_sectors value, continue to limit to this value for safety. Signed-off-by: John Garry Reviewed-by: Damien Le Moal Acked-by: Martin K. Petersen Signed-off-by: Christoph Hellwig --- drivers/scsi/sd.c | 2 ++ include/scsi/scsi_host.h | 1 + 2 files changed, 3 insertions(+) (limited to 'drivers/scsi') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index a1a2ac09066f..3eaee1f7aaca 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -3296,6 +3296,8 @@ static int sd_revalidate_disk(struct gendisk *disk) (sector_t)BLK_DEF_MAX_SECTORS); } + rw_max = min_not_zero(rw_max, sdp->host->opt_sectors); + /* Do not exceed controller limit */ rw_max = min(rw_max, queue_max_hw_sectors(q)); diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 667d889b92b5..d32a84b2bb40 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -607,6 +607,7 @@ struct Scsi_Host { short unsigned int sg_tablesize; short unsigned int sg_prot_tablesize; unsigned int max_sectors; + unsigned int opt_sectors; unsigned int max_segment_size; unsigned long dma_boundary; unsigned long virt_boundary_mask; -- cgit v1.2.3 From 4cbfca5f7750520ff993a0d6eb79cc4a6f6cee97 Mon Sep 17 00:00:00 2001 From: John Garry Date: Thu, 14 Jul 2022 19:15:28 +0800 Subject: scsi: scsi_transport_sas: cap shost opt_sectors according to DMA optimal limit Streaming DMA mappings may be considerably slower when mappings go through an IOMMU and the total mapping length is somewhat long. This is because the IOMMU IOVA code allocates and free an IOVA for each mapping, which may affect performance. For performance reasons set the request queue max_sectors from dma_opt_mapping_size(), which knows this mapping limit. Signed-off-by: John Garry Reviewed-by: Damien Le Moal Signed-off-by: Christoph Hellwig --- drivers/scsi/scsi_transport_sas.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/scsi') diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index 12bff64dade6..2f88c61216ee 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c @@ -225,6 +225,7 @@ static int sas_host_setup(struct transport_container *tc, struct device *dev, { struct Scsi_Host *shost = dev_to_shost(dev); struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); + struct device *dma_dev = shost->dma_dev; INIT_LIST_HEAD(&sas_host->rphy_list); mutex_init(&sas_host->lock); @@ -236,6 +237,11 @@ static int sas_host_setup(struct transport_container *tc, struct device *dev, dev_printk(KERN_ERR, dev, "fail to a bsg device %d\n", shost->host_no); + if (dma_dev->dma_mask) { + shost->opt_sectors = min_t(unsigned int, shost->max_sectors, + dma_opt_mapping_size(dma_dev) >> SECTOR_SHIFT); + } + return 0; } -- cgit v1.2.3 From c9337ad4390cdff8877e64824c2a2827d815743d Mon Sep 17 00:00:00 2001 From: John Garry Date: Tue, 19 Jul 2022 17:51:04 +0800 Subject: scsi: sd: Add a comment about limiting max_sectors to shost optimal limit Add a comment about limiting the default the SCSI disk request_queue max_sectors initial value to that of the SCSI host optimal sectors limit. Suggested-by: Damien Le Moal Signed-off-by: John Garry Reviewed-by: Damien Le Moal Reviewed-by: Martin K. Petersen Signed-off-by: Christoph Hellwig --- drivers/scsi/sd.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/scsi') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 3eaee1f7aaca..ed9f43f9512e 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -3296,6 +3296,11 @@ static int sd_revalidate_disk(struct gendisk *disk) (sector_t)BLK_DEF_MAX_SECTORS); } + /* + * Limit default to SCSI host optimal sector limit if set. There may be + * an impact on performance for when the size of a request exceeds this + * host limit. + */ rw_max = min_not_zero(rw_max, sdp->host->opt_sectors); /* Do not exceed controller limit */ -- cgit v1.2.3