FROMLIST: scsi: core: Implement reserved command handling
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. Change-Id: Ie18285c756bafe152a8ca17109469e4518366039 Signed-off-by: Hannes Reinecke <hare@suse.de> [ bvanassche: modified patch description ] Cc: John Garry <john.g.garry@oracle.com> Signed-off-by: Bart Van Assche <bvanassche@acm.org> Bug: 408217416 Link: https://lore.kernel.org/linux-scsi/20250403211937.2225615-5-bvanassche@acm.org/ Signed-off-by: Bart Van Assche <bvanassche@google.com>
This commit is contained in:
committed by
Carlos Llamas
parent
26febb7cde
commit
d48d0d0892
@@ -495,6 +495,9 @@ struct Scsi_Host *scsi_host_alloc(const struct scsi_host_template *sht, int priv
|
||||
if (sht->virt_boundary_mask)
|
||||
shost->virt_boundary_mask = sht->virt_boundary_mask;
|
||||
|
||||
if (sht->nr_reserved_cmds)
|
||||
shost->nr_reserved_cmds = sht->nr_reserved_cmds;
|
||||
|
||||
device_initialize(&shost->shost_gendev);
|
||||
dev_set_name(&shost->shost_gendev, "host%d", shost->host_no);
|
||||
shost->shost_gendev.bus = &scsi_bus_type;
|
||||
|
||||
@@ -391,6 +391,8 @@ void scsi_device_unbusy(struct scsi_device *sdev, struct scsi_cmnd *cmd)
|
||||
struct Scsi_Host *shost = sdev->host;
|
||||
struct scsi_target *starget = scsi_target(sdev);
|
||||
|
||||
WARN_ON_ONCE(cmd->budget_token < 0);
|
||||
|
||||
scsi_dec_host_busy(shost, cmd);
|
||||
|
||||
if (starget->can_queue > 0)
|
||||
@@ -2073,7 +2075,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);
|
||||
tag_set->flags = BLK_MQ_F_SHOULD_MERGE;
|
||||
|
||||
@@ -380,10 +380,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 calcumate 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
|
||||
@@ -619,6 +628,11 @@ 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;
|
||||
short cmd_per_lun;
|
||||
short unsigned int sg_tablesize;
|
||||
@@ -639,6 +653,12 @@ struct Scsi_Host {
|
||||
*/
|
||||
unsigned nr_hw_queues;
|
||||
unsigned nr_maps;
|
||||
|
||||
/*
|
||||
* Number of reserved commands to allocate, if any.
|
||||
*/
|
||||
unsigned int nr_reserved_cmds;
|
||||
|
||||
unsigned active_mode:2;
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user