scsi: qedf: Fix race between ELS completion and flushing ELS request
authorSaurav Kashyap <skashyap@marvell.com>
Fri, 7 Aug 2020 11:06:56 +0000 (04:06 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Fri, 21 Aug 2020 01:41:52 +0000 (21:41 -0400)
Fix race between ELS completion and flushing ELS request.

Link: https://lore.kernel.org/r/20200807110656.19965-8-jhasan@marvell.com
Signed-off-by: Saurav Kashyap <skashyap@marvell.com>
Signed-off-by: Javed Hasan <jhasan@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/qedf/qedf_els.c
drivers/scsi/qedf/qedf_io.c

index e2e80ea..6cb8c9b 100644 (file)
@@ -143,6 +143,7 @@ void qedf_process_els_compl(struct qedf_ctx *qedf, struct fcoe_cqe *cqe,
        struct qedf_ioreq *els_req)
 {
        struct fcoe_cqe_midpath_info *mp_info;
+       struct qedf_rport *fcport;
 
        QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS, "Entered with xid = 0x%x"
                   " cmd_type = %d.\n", els_req->xid, els_req->cmd_type);
@@ -156,6 +157,19 @@ void qedf_process_els_compl(struct qedf_ctx *qedf, struct fcoe_cqe *cqe,
                return;
        }
 
+       fcport = els_req->fcport;
+
+       /* When flush is active,
+        * let the cmds be completed from the cleanup context
+        */
+       if (test_bit(QEDF_RPORT_IN_TARGET_RESET, &fcport->flags) ||
+               test_bit(QEDF_RPORT_IN_LUN_RESET, &fcport->flags)) {
+               QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO,
+                       "Dropping ELS completion xid=0x%x as fcport is flushing",
+                       els_req->xid);
+               return;
+       }
+
        clear_bit(QEDF_CMD_OUTSTANDING, &els_req->flags);
 
        /* Kill the ELS timer */
index 7969f3a..86c8afb 100644 (file)
@@ -1562,6 +1562,8 @@ static void qedf_flush_els_req(struct qedf_ctx *qedf,
         */
        els_req->event = QEDF_IOREQ_EV_ELS_FLUSH;
 
+       clear_bit(QEDF_CMD_OUTSTANDING, &els_req->flags);
+
        /* Cancel the timer */
        cancel_delayed_work_sync(&els_req->timeout_work);