diff options
author | Tyrel Datwyler <tyreld@linux.ibm.com> | 2021-01-06 21:18:35 +0100 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2021-01-08 04:37:13 +0100 |
commit | 654080d02edb60a5842cae9cf14ff83fd352305f (patch) | |
tree | 268a0b828dcd418d2f8a2f48f6f2f8f4bf7bdde5 | |
parent | scsi: ibmvfc: Complete commands outside the host/queue lock (diff) | |
download | linux-654080d02edb60a5842cae9cf14ff83fd352305f.tar.xz linux-654080d02edb60a5842cae9cf14ff83fd352305f.zip |
scsi: ibmvfc: Relax locking around ibmvfc_queuecommand()
The driver's queuecommand routine is still wrapped to hold the host lock
for the duration of the call. This will become problematic when moving to
multiple queues due to the lock contention preventing asynchronous
submissions to mulitple queues. There is no real legitimate reason to hold
the host lock, and previous patches have insured proper protection of
moving ibmvfc_event objects between free and sent lists.
Link: https://lore.kernel.org/r/20210106201835.1053593-6-tyreld@linux.ibm.com
Reviewed-by: Brian King <brking@linux.vnet.ibm.com>
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r-- | drivers/scsi/ibmvscsi/ibmvfc.c | 12 |
1 files changed, 4 insertions, 8 deletions
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index f680f96d5d06..ff86c43b4b33 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -1793,10 +1793,9 @@ static struct ibmvfc_cmd *ibmvfc_init_vfc_cmd(struct ibmvfc_event *evt, struct s * Returns: * 0 on success / other on failure **/ -static int ibmvfc_queuecommand_lck(struct scsi_cmnd *cmnd, - void (*done) (struct scsi_cmnd *)) +static int ibmvfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd) { - struct ibmvfc_host *vhost = shost_priv(cmnd->device->host); + struct ibmvfc_host *vhost = shost_priv(shost); struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device)); struct ibmvfc_cmd *vfc_cmd; struct ibmvfc_fcp_cmd_iu *iu; @@ -1806,7 +1805,7 @@ static int ibmvfc_queuecommand_lck(struct scsi_cmnd *cmnd, if (unlikely((rc = fc_remote_port_chkready(rport))) || unlikely((rc = ibmvfc_host_chkready(vhost)))) { cmnd->result = rc; - done(cmnd); + cmnd->scsi_done(cmnd); return 0; } @@ -1814,7 +1813,6 @@ static int ibmvfc_queuecommand_lck(struct scsi_cmnd *cmnd, evt = ibmvfc_get_event(&vhost->crq); ibmvfc_init_event(evt, ibmvfc_scsi_done, IBMVFC_CMD_FORMAT); evt->cmnd = cmnd; - cmnd->scsi_done = done; vfc_cmd = ibmvfc_init_vfc_cmd(evt, cmnd->device); iu = ibmvfc_get_fcp_iu(vhost, vfc_cmd); @@ -1841,12 +1839,10 @@ static int ibmvfc_queuecommand_lck(struct scsi_cmnd *cmnd, "Failed to map DMA buffer for command. rc=%d\n", rc); cmnd->result = DID_ERROR << 16; - done(cmnd); + cmnd->scsi_done(cmnd); return 0; } -static DEF_SCSI_QCMD(ibmvfc_queuecommand) - /** * ibmvfc_sync_completion - Signal that a synchronous command has completed * @evt: ibmvfc event struct |