diff options
author | Kashyap.Desai@avagotech.com <Kashyap.Desai@avagotech.com> | 2014-08-20 19:24:33 +0530 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2015-04-02 19:34:54 -0600 |
commit | d0578da7d5bb9e36538ce0b215cf42ae96420ef1 (patch) | |
tree | 45969d31c75e4180009e87e61d3924f4ab975392 | |
parent | 08374bae5a583ce4ea5e57d60928f1aa63b21d3d (diff) |
scsi: add use_cmd_list flagv3.10-scsi-mq
Add a use_cmd_list flag in struct Scsi_Host to request keeping track of
all outstanding commands per device.
Default behaviour is not to keep track of cmd_list per sdev, as this may
introduce lock contention. (overhead is more on multi-node NUMA.), and
only enable it on the two drivers that need it.
Signed-off-by: Kashyap Desai <kashyap.desai@avagotech.com>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Christoph Hellwig <hch@lst.de>
-rw-r--r-- | drivers/scsi/aacraid/linit.c | 1 | ||||
-rw-r--r-- | drivers/scsi/dpt_i2o.c | 1 | ||||
-rw-r--r-- | drivers/scsi/scsi_lib.c | 24 | ||||
-rw-r--r-- | include/scsi/scsi_host.h | 1 |
4 files changed, 15 insertions, 12 deletions
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 4921ed19a027..21d82534e4ad 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -1152,6 +1152,7 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) shost->irq = pdev->irq; shost->unique_id = unique_id; shost->max_cmd_len = 16; + shost->use_cmd_list = 1; aac = (struct aac_dev *)shost->hostdata; aac->base_start = pci_resource_start(pdev, 0); diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c index 19e1b422260a..204b2605723b 100644 --- a/drivers/scsi/dpt_i2o.c +++ b/drivers/scsi/dpt_i2o.c @@ -2372,6 +2372,7 @@ static s32 adpt_scsi_host_alloc(adpt_hba* pHba, struct scsi_host_template *sht) host->unique_id = (u32)sys_tbl_pa + pHba->unit; host->sg_tablesize = pHba->sg_tablesize; host->can_queue = pHba->post_fifo_size; + host->use_cmd_list = 1; return 0; } diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index eb4ac5865d1e..de741c400af1 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -728,16 +728,18 @@ static void scsi_mq_free_sgtables(struct scsi_cmnd *cmd) static void scsi_mq_uninit_cmd(struct scsi_cmnd *cmd) { struct scsi_device *sdev = cmd->device; + struct Scsi_Host *shost = sdev->host; unsigned long flags; - BUG_ON(list_empty(&cmd->list)); - scsi_mq_free_sgtables(cmd); scsi_uninit_cmd(cmd); - spin_lock_irqsave(&sdev->list_lock, flags); - list_del_init(&cmd->list); - spin_unlock_irqrestore(&sdev->list_lock, flags); + if (shost->use_cmd_list) { + BUG_ON(list_empty(&cmd->list)); + spin_lock_irqsave(&sdev->list_lock, flags); + list_del_init(&cmd->list); + spin_unlock_irqrestore(&sdev->list_lock, flags); + } } /* @@ -1850,13 +1852,11 @@ static int scsi_mq_prep_fn(struct request *req) INIT_DELAYED_WORK(&cmd->abort_work, scmd_eh_abort_handler); cmd->jiffies_at_alloc = jiffies; - /* - * XXX: cmd_list lookups are only used by two drivers, try to get - * rid of this list in common code. - */ - spin_lock_irq(&sdev->list_lock); - list_add_tail(&cmd->list, &sdev->cmd_list); - spin_unlock_irq(&sdev->list_lock); + if (shost->use_cmd_list) { + spin_lock_irq(&sdev->list_lock); + list_add_tail(&cmd->list, &sdev->cmd_list); + spin_unlock_irq(&sdev->list_lock); + } sg = (void *)cmd + sizeof(struct scsi_cmnd) + shost->hostt->cmd_size; cmd->sdb.table.sgl = sg; diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index c5fc134372d6..543f36d06550 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -700,6 +700,7 @@ struct Scsi_Host { unsigned no_write_same:1; unsigned use_blk_mq:1; + unsigned use_cmd_list:1; /* * Optional work queue to be utilized by the transport |