When ibmvfc_send_event() returns H_CLOSED the event is freed without
notifying the NVMe-FC transport. The caller ibmvfc_nvme_fcp_io() returns
SCSI_MLQUEUE_HOST_BUSY back to the transport, which is a SCSI midlayer
concept the NVMe-FC transport does not interpret. The result is that the
NVMe-FC transport is left waiting on a request that was silently dropped,
causing the I/O to hang permanently.

Fix this by calling fcp_req->done() with a -EBUSY status before freeing
the event in the H_CLOSED path, consistent with how other FC-NVMe LLDDs
(e.g. lpfc) signal a retryable transport-level failure to the NVMe-FC
transport.

Fixes: 73c13e30c56f ("scsi: ibmvfc: implement nvme-fc IO command submission 
callback")
Signed-off-by: Tyrel Datwyler <[email protected]>
---
 drivers/scsi/ibmvscsi/ibmvfc-core.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/scsi/ibmvscsi/ibmvfc-core.c 
b/drivers/scsi/ibmvscsi/ibmvfc-core.c
index 6c243b2a84d7..26a73db66254 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc-core.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc-core.c
@@ -1845,6 +1845,10 @@ int ibmvfc_send_event(struct ibmvfc_event *evt,
                                dev_warn(vhost->dev, "Send warning. Receive 
queue closed, will retry.\n");
                        if (evt->cmnd)
                                scsi_dma_unmap(evt->cmnd);
+                       else if (evt->fcp_req) {
+                               evt->fcp_req->status = -EBUSY;
+                               evt->fcp_req->done(evt->fcp_req);
+                       }
                        ibmvfc_free_event(evt);
                        return SCSI_MLQUEUE_HOST_BUSY;
                }
-- 
2.55.0


Reply via email to