scsi: core: Add a no_highmem flag to struct Scsi_Host
authorChristoph Hellwig <hch@lst.de>
Tue, 9 Apr 2024 14:37:31 +0000 (16:37 +0200)
committerMartin K. Petersen <martin.petersen@oracle.com>
Fri, 12 Apr 2024 01:37:48 +0000 (21:37 -0400)
While we really should be killing the block layer bounce buffering ASAP, I
even more urgently need to stop the drivers to fiddle with the limits from
->slave_configure.  Add a no_highmem flag to the Scsi_Host to centralize
this setting and switch the remaining four drivers that use block layer
bounce buffering to it.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/r/20240409143748.980206-7-hch@lst.de
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: John Garry <john.g.garry@oracle.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/aha152x.c
drivers/scsi/imm.c
drivers/scsi/ppa.c
drivers/scsi/scsi_lib.c
drivers/usb/storage/scsiglue.c
drivers/usb/storage/usb.c
include/scsi/scsi_host.h

index 055adb349b0e416a081ab05f0db1068a3e6d93dc..83f16fc14d96307acdf431cfff922a3e5092443d 100644 (file)
@@ -746,6 +746,7 @@ struct Scsi_Host *aha152x_probe_one(struct aha152x_setup *setup)
        /* need to have host registered before triggering any interrupt */
        list_add_tail(&HOSTDATA(shpnt)->host_list, &aha152x_host_list);
 
+       shpnt->no_highmem = true;
        shpnt->io_port   = setup->io_port;
        shpnt->n_io_port = IO_RANGE;
        shpnt->irq       = setup->irq;
@@ -2940,12 +2941,6 @@ static int aha152x_show_info(struct seq_file *m, struct Scsi_Host *shpnt)
        return 0;
 }
 
-static int aha152x_adjust_queue(struct scsi_device *device)
-{
-       blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_HIGH);
-       return 0;
-}
-
 static const struct scsi_host_template aha152x_driver_template = {
        .module                         = THIS_MODULE,
        .name                           = AHA152X_REVID,
@@ -2961,7 +2956,6 @@ static const struct scsi_host_template aha152x_driver_template = {
        .this_id                        = 7,
        .sg_tablesize                   = SG_ALL,
        .dma_boundary                   = PAGE_SIZE - 1,
-       .slave_alloc                    = aha152x_adjust_queue,
        .cmd_size                       = sizeof(struct aha152x_cmd_priv),
 };
 
index 180a5ddedb2cdaa0c9f57050618707ed97045337..21339da505f1ead5696bf093673366938b6d05e5 100644 (file)
@@ -1100,16 +1100,6 @@ static int device_check(imm_struct *dev, bool autodetect)
        return -ENODEV;
 }
 
-/*
- * imm cannot deal with highmem, so this causes all IO pages for this host
- * to reside in low memory (hence mapped)
- */
-static int imm_adjust_queue(struct scsi_device *device)
-{
-       blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_HIGH);
-       return 0;
-}
-
 static const struct scsi_host_template imm_template = {
        .module                 = THIS_MODULE,
        .proc_name              = "imm",
@@ -1123,7 +1113,6 @@ static const struct scsi_host_template imm_template = {
        .this_id                = 7,
        .sg_tablesize           = SG_ALL,
        .can_queue              = 1,
-       .slave_alloc            = imm_adjust_queue,
        .cmd_size               = sizeof(struct scsi_pointer),
 };
 
@@ -1235,6 +1224,7 @@ static int __imm_attach(struct parport *pb)
        host = scsi_host_alloc(&imm_template, sizeof(imm_struct *));
        if (!host)
                goto out1;
+       host->no_highmem = true;
        host->io_port = pb->base;
        host->n_io_port = ports;
        host->dma_channel = -1;
index d592ee9170c11f373971028a804f44a6ba6042b7..8300f0bdddb37a4a1759f7779f7c9060ed7e66d0 100644 (file)
@@ -986,12 +986,6 @@ second_pass:
        return -ENODEV;
 }
 
-static int ppa_adjust_queue(struct scsi_device *device)
-{
-       blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_HIGH);
-       return 0;
-}
-
 static const struct scsi_host_template ppa_template = {
        .module                 = THIS_MODULE,
        .proc_name              = "ppa",
@@ -1005,7 +999,6 @@ static const struct scsi_host_template ppa_template = {
        .this_id                = -1,
        .sg_tablesize           = SG_ALL,
        .can_queue              = 1,
-       .slave_alloc            = ppa_adjust_queue,
        .cmd_size               = sizeof(struct scsi_pointer),
 };
 
@@ -1111,6 +1104,7 @@ static int __ppa_attach(struct parport *pb)
        host = scsi_host_alloc(&ppa_template, sizeof(ppa_struct *));
        if (!host)
                goto out1;
+       host->no_highmem = true;
        host->io_port = pb->base;
        host->n_io_port = ports;
        host->dma_channel = -1;
index 1deca84914e87a38e2426d6255d0331f08a4a8fe..f1936f98abe3e2f1f54c643bd497355c8565fc09 100644 (file)
@@ -1995,6 +1995,9 @@ void scsi_init_limits(struct Scsi_Host *shost, struct queue_limits *lim)
         */
        lim->dma_alignment = max(4, dma_get_cache_alignment()) - 1;
 
+       if (shost->no_highmem)
+               lim->bounce = BLK_BOUNCE_HIGH;
+
        dma_set_seg_boundary(dev, shost->dma_boundary);
        dma_set_max_seg_size(dev, shost->max_segment_size);
 }
index 12cf9940e5b6759167f9ae7450df8af92a85c63a..1d14c678f3d3e3df69024291029b2df1f257b503 100644 (file)
@@ -40,7 +40,6 @@
 #include <scsi/scsi_eh.h>
 
 #include "usb.h"
-#include <linux/usb/hcd.h>
 #include "scsiglue.h"
 #include "debug.h"
 #include "transport.h"
@@ -130,15 +129,6 @@ static int slave_configure(struct scsi_device *sdev)
                min_t(size_t, queue_max_hw_sectors(sdev->request_queue),
                      dma_max_mapping_size(dev) >> SECTOR_SHIFT));
 
-       /*
-        * Some USB host controllers can't do DMA; they have to use PIO.
-        * For such controllers we need to make sure the block layer sets
-        * up bounce buffers in addressable memory.
-        */
-       if (!hcd_uses_dma(bus_to_hcd(us->pusb_dev->bus)) ||
-                       (bus_to_hcd(us->pusb_dev->bus)->localmem_pool != NULL))
-               blk_queue_bounce_limit(sdev->request_queue, BLK_BOUNCE_HIGH);
-
        /*
         * We can't put these settings in slave_alloc() because that gets
         * called before the device type is known.  Consequently these
index d1ad6a2509ab7fe3828184a9254d83ce7c12b1cf..a49a31639f6f0c9238abb5165b76d09c3336e82b 100644 (file)
@@ -47,6 +47,7 @@
 #include <scsi/scsi_device.h>
 
 #include "usb.h"
+#include <linux/usb/hcd.h>
 #include "scsiglue.h"
 #include "transport.h"
 #include "protocol.h"
@@ -961,6 +962,15 @@ int usb_stor_probe1(struct us_data **pus,
        if (result)
                goto BadDevice;
 
+       /*
+        * Some USB host controllers can't do DMA; they have to use PIO.
+        * For such controllers we need to make sure the block layer sets
+        * up bounce buffers in addressable memory.
+        */
+       if (!hcd_uses_dma(bus_to_hcd(us->pusb_dev->bus)) ||
+           bus_to_hcd(us->pusb_dev->bus)->localmem_pool)
+               host->no_highmem = true;
+
        /* Get the unusual_devs entries and the descriptors */
        result = get_device_info(us, id, unusual_dev);
        if (result)
index b259d42a1e1affd9d82be3975782b1b526e97437..6d77c48e8311fb892ee280e806a2fec7ad2c140d 100644 (file)
@@ -665,6 +665,8 @@ struct Scsi_Host {
        /* The transport requires the LUN bits NOT to be stored in CDB[1] */
        unsigned no_scsi2_lun_in_cdb:1;
 
+       unsigned no_highmem:1;
+
        /*
         * Optional work queue to be utilized by the transport
         */