The legacy CRQ holds the host lock the even while completing commands. This presents a problem when in legacy single queue mode and nr_hw_queues is greater than one since calling scsi_done() introduces the potential for deadlock. If nr_hw_queues is greater than one drop the hostlock in the legacy CRQ path when completing a command. Signed-off-by: Tyrel Datwyler <tyreld@xxxxxxxxxxxxx> --- drivers/scsi/ibmvscsi/ibmvfc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index e499599662ec..e2200bdff2be 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -2969,6 +2969,7 @@ static void ibmvfc_handle_crq(struct ibmvfc_crq *crq, struct ibmvfc_host *vhost) { long rc; struct ibmvfc_event *evt = (struct ibmvfc_event *)be64_to_cpu(crq->ioba); + unsigned long flags; switch (crq->valid) { case IBMVFC_CRQ_INIT_RSP: @@ -3039,7 +3040,12 @@ static void ibmvfc_handle_crq(struct ibmvfc_crq *crq, struct ibmvfc_host *vhost) del_timer(&evt->timer); list_del(&evt->queue); ibmvfc_trc_end(evt); - evt->done(evt); + if (nr_scsi_hw_queues > 1) { + spin_unlock_irqrestore(vhost->host->host_lock, flags); + evt->done(evt); + spin_lock_irqsave(vhost->host->host_lock, flags); + } else + evt->done(evt); } /** -- 2.27.0