]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
scsi: core: Support allocating reserved commands
authorHannes Reinecke <hare@suse.de>
Fri, 31 Oct 2025 20:39:09 +0000 (13:39 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 12 Nov 2025 22:02:30 +0000 (17:02 -0500)
Quite some drivers are using management commands internally. These
commands typically use the same tag pool as regular SCSI commands. Tags
for these management commands are set aside before allocating the
block-mq tag bitmap for regular SCSI commands. The block layer already
supports this via the reserved tag mechanism. Add a new field
'nr_reserved_cmds' to the SCSI host template to instruct the block layer
to set aside a tag space for these management commands by using reserved
tags. Exclude reserved commands from .can_queue because .can_queue is
visible in sysfs.

[ bvanassche: modified patch title and patch description. Left out the
  following statements: "if (sht->nr_reserved_cmds)" and also
  "if (sdev->host->nr_reserved_cmds) flags |= BLK_MQ_REQ_RESERVED;". Moved
  nr_reserved_cmds declarations and statements close to the
  corresponding can_queue declarations and statements. See also
  https://lore.kernel.org/linux-scsi/20210503150333.130310-11-hare@suse.de/ ]

Signed-off-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: John Garry <john.g.garry@oracle.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Link: https://patch.msgid.link/20251031204029.2883185-2-bvanassche@acm.org
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/hosts.c
drivers/scsi/scsi_lib.c
include/scsi/scsi_host.h

index eb224a338fa21be7661e24af410f0913c1241719..8b7f5fafa9e08dde4777b3e085d8708feb83f51e 100644 (file)
@@ -436,6 +436,7 @@ struct Scsi_Host *scsi_host_alloc(const struct scsi_host_template *sht, int priv
        shost->hostt = sht;
        shost->this_id = sht->this_id;
        shost->can_queue = sht->can_queue;
+       shost->nr_reserved_cmds = sht->nr_reserved_cmds;
        shost->sg_tablesize = sht->sg_tablesize;
        shost->sg_prot_tablesize = sht->sg_prot_tablesize;
        shost->cmd_per_lun = sht->cmd_per_lun;
index d7e42293b864553d79a3cb9a55f2f433dbcb1fcc..d52bbbe5a357b7a49eaafab99bf675a2cee9e0ac 100644 (file)
@@ -2083,7 +2083,8 @@ int scsi_mq_setup_tags(struct Scsi_Host *shost)
                tag_set->ops = &scsi_mq_ops_no_commit;
        tag_set->nr_hw_queues = shost->nr_hw_queues ? : 1;
        tag_set->nr_maps = shost->nr_maps ? : 1;
-       tag_set->queue_depth = shost->can_queue;
+       tag_set->queue_depth = shost->can_queue + shost->nr_reserved_cmds;
+       tag_set->reserved_tags = shost->nr_reserved_cmds;
        tag_set->cmd_size = cmd_size;
        tag_set->numa_node = dev_to_node(shost->dma_dev);
        if (shost->hostt->tag_alloc_policy_rr)
index f5a24326123605b38baabf40f8430a2dd33a48d4..7b8f144ccf7d82fd8a422e229b80af0e905c8032 100644 (file)
@@ -375,10 +375,19 @@ struct scsi_host_template {
        /*
         * This determines if we will use a non-interrupt driven
         * or an interrupt driven scheme.  It is set to the maximum number
-        * of simultaneous commands a single hw queue in HBA will accept.
+        * of simultaneous commands a single hw queue in HBA will accept
+        * excluding internal commands.
         */
        int can_queue;
 
+       /*
+        * This determines how many commands the HBA will set aside
+        * for internal commands. This number will be added to
+        * @can_queue to calculate the maximum number of simultaneous
+        * commands sent to the host.
+        */
+       int nr_reserved_cmds;
+
        /*
         * In many instances, especially where disconnect / reconnect are
         * supported, our host also has an ID on the SCSI bus.  If this is
@@ -611,7 +620,17 @@ struct Scsi_Host {
        unsigned short max_cmd_len;
 
        int this_id;
+
+       /*
+        * Number of commands this host can handle at the same time.
+        * This excludes reserved commands as specified by nr_reserved_cmds.
+        */
        int can_queue;
+       /*
+        * Number of reserved commands to allocate, if any.
+        */
+       unsigned int nr_reserved_cmds;
+
        short cmd_per_lun;
        short unsigned int sg_tablesize;
        short unsigned int sg_prot_tablesize;