scsi: ibmvfc: Relax locking around ibmvfc_queuecommand()
authorTyrel Datwyler <tyreld@linux.ibm.com>
Wed, 6 Jan 2021 20:18:35 +0000 (14:18 -0600)
committerMartin K. Petersen <martin.petersen@oracle.com>
Fri, 8 Jan 2021 03:37:13 +0000 (22:37 -0500)
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>
drivers/scsi/ibmvscsi/ibmvfc.c

index f680f96..ff86c43 100644 (file)
@@ -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