Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

scsi: core: Support allocating reserved commands

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>

authored by

Hannes Reinecke and committed by
Martin K. Petersen
d604e1ec e9ff858c

+23 -2
+1
drivers/scsi/hosts.c
··· 436 436 shost->hostt = sht; 437 437 shost->this_id = sht->this_id; 438 438 shost->can_queue = sht->can_queue; 439 + shost->nr_reserved_cmds = sht->nr_reserved_cmds; 439 440 shost->sg_tablesize = sht->sg_tablesize; 440 441 shost->sg_prot_tablesize = sht->sg_prot_tablesize; 441 442 shost->cmd_per_lun = sht->cmd_per_lun;
+2 -1
drivers/scsi/scsi_lib.c
··· 2083 2083 tag_set->ops = &scsi_mq_ops_no_commit; 2084 2084 tag_set->nr_hw_queues = shost->nr_hw_queues ? : 1; 2085 2085 tag_set->nr_maps = shost->nr_maps ? : 1; 2086 - tag_set->queue_depth = shost->can_queue; 2086 + tag_set->queue_depth = shost->can_queue + shost->nr_reserved_cmds; 2087 + tag_set->reserved_tags = shost->nr_reserved_cmds; 2087 2088 tag_set->cmd_size = cmd_size; 2088 2089 tag_set->numa_node = dev_to_node(shost->dma_dev); 2089 2090 if (shost->hostt->tag_alloc_policy_rr)
+20 -1
include/scsi/scsi_host.h
··· 375 375 /* 376 376 * This determines if we will use a non-interrupt driven 377 377 * or an interrupt driven scheme. It is set to the maximum number 378 - * of simultaneous commands a single hw queue in HBA will accept. 378 + * of simultaneous commands a single hw queue in HBA will accept 379 + * excluding internal commands. 379 380 */ 380 381 int can_queue; 382 + 383 + /* 384 + * This determines how many commands the HBA will set aside 385 + * for internal commands. This number will be added to 386 + * @can_queue to calculate the maximum number of simultaneous 387 + * commands sent to the host. 388 + */ 389 + int nr_reserved_cmds; 381 390 382 391 /* 383 392 * In many instances, especially where disconnect / reconnect are ··· 620 611 unsigned short max_cmd_len; 621 612 622 613 int this_id; 614 + 615 + /* 616 + * Number of commands this host can handle at the same time. 617 + * This excludes reserved commands as specified by nr_reserved_cmds. 618 + */ 623 619 int can_queue; 620 + /* 621 + * Number of reserved commands to allocate, if any. 622 + */ 623 + unsigned int nr_reserved_cmds; 624 + 624 625 short cmd_per_lun; 625 626 short unsigned int sg_tablesize; 626 627 short unsigned int sg_prot_tablesize;