diff options
author | Mike Christie <michael.christie@oracle.com> | 2020-11-01 12:59:33 -0600 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2020-11-04 22:39:38 -0500 |
commit | 1526d9f10c6184031e42afad0adbdde1213e8ad1 (patch) | |
tree | 11d7de3c7d694af86399e8b9458a13f5943a6840 /drivers/target/target_core_device.c | |
parent | 6f55b06f9b0722607cbac2140875d790395435f2 (diff) | |
download | linux-1526d9f10c6184031e42afad0adbdde1213e8ad1.tar.gz |
scsi: target: Make state_list per CPU
Do a state_list/execute_task_lock per CPU, so we can do submissions from
different CPUs without contention with each other.
Note: tcm_fc was passing TARGET_SCF_USE_CPUID, but never set cpuid. The
assumption is that it wanted to set the cpuid to the CPU it was submitting
from so it will get this behavior with this patch.
[mkp: s/printk/pr_err/ + resolve COMPARE AND WRITE patch conflict]
Link: https://lore.kernel.org/r/1604257174-4524-8-git-send-email-michael.christie@oracle.com
Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
Signed-off-by: Mike Christie <michael.christie@oracle.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/target/target_core_device.c')
-rw-r--r-- | drivers/target/target_core_device.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 1f673fbc28f9..7787c527aad3 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -721,11 +721,24 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name) { struct se_device *dev; struct se_lun *xcopy_lun; + int i; dev = hba->backend->ops->alloc_device(hba, name); if (!dev) return NULL; + dev->queues = kcalloc(nr_cpu_ids, sizeof(*dev->queues), GFP_KERNEL); + if (!dev->queues) { + dev->transport->free_device(dev); + return NULL; + } + + dev->queue_cnt = nr_cpu_ids; + for (i = 0; i < dev->queue_cnt; i++) { + INIT_LIST_HEAD(&dev->queues[i].state_list); + spin_lock_init(&dev->queues[i].lock); + } + dev->se_hba = hba; dev->transport = hba->backend->ops; dev->transport_flags = dev->transport->transport_flags_default; @@ -735,9 +748,7 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name) INIT_LIST_HEAD(&dev->dev_sep_list); INIT_LIST_HEAD(&dev->dev_tmr_list); INIT_LIST_HEAD(&dev->delayed_cmd_list); - INIT_LIST_HEAD(&dev->state_list); INIT_LIST_HEAD(&dev->qf_cmd_list); - spin_lock_init(&dev->execute_task_lock); spin_lock_init(&dev->delayed_cmd_lock); spin_lock_init(&dev->dev_reservation_lock); spin_lock_init(&dev->se_port_lock); @@ -1010,6 +1021,7 @@ void target_free_device(struct se_device *dev) if (dev->transport->free_prot) dev->transport->free_prot(dev); + kfree(dev->queues); dev->transport->free_device(dev); } |