bnx2fc: Remove explicit logouts.
authorChad Dupuis <chad.dupuis@qlogic.com>
Mon, 19 Oct 2015 19:40:39 +0000 (15:40 -0400)
committerJames Bottomley <JBottomley@Odin.com>
Tue, 10 Nov 2015 01:31:34 +0000 (17:31 -0800)
Explicit logouts from bnx2fc were causing race conditions in either returning
stale SCSI commands or not allowing a target to log back in.

Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: Tomas Henzl <thenzl@redhat.com>
Signed-off-by: James Bottomley <JBottomley@Odin.com>
drivers/scsi/bnx2fc/bnx2fc.h
drivers/scsi/bnx2fc/bnx2fc_els.c
drivers/scsi/bnx2fc/bnx2fc_io.c
drivers/scsi/bnx2fc/bnx2fc_tgt.c

index 0e2aa65..d46267d 100644 (file)
@@ -303,7 +303,6 @@ struct bnx2fc_rport {
 #define BNX2FC_FLAG_OFLD_REQ_CMPL      0x5
 #define BNX2FC_FLAG_CTX_ALLOC_FAILURE  0x6
 #define BNX2FC_FLAG_UPLD_REQ_COMPL     0x7
-#define BNX2FC_FLAG_EXPL_LOGO          0x8
 #define BNX2FC_FLAG_DISABLE_FAILED     0x9
 #define BNX2FC_FLAG_ENABLED            0xa
 
index 0d0ab2e..5beea77 100644 (file)
@@ -689,8 +689,7 @@ static int bnx2fc_initiate_els(struct bnx2fc_rport *tgt, unsigned int op,
                rc = -EINVAL;
                goto els_err;
        }
-       if (!(test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags)) ||
-            (test_bit(BNX2FC_FLAG_EXPL_LOGO, &tgt->flags))) {
+       if (!(test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags))) {
                printk(KERN_ERR PFX "els 0x%x: tgt not ready\n", op);
                rc = -EINVAL;
                goto els_err;
index 8ae0621..0002caf 100644 (file)
@@ -40,11 +40,8 @@ static void bnx2fc_cmd_timeout(struct work_struct *work)
 {
        struct bnx2fc_cmd *io_req = container_of(work, struct bnx2fc_cmd,
                                                 timeout_work.work);
-       struct fc_lport *lport;
-       struct fc_rport_priv *rdata;
        u8 cmd_type = io_req->cmd_type;
        struct bnx2fc_rport *tgt = io_req->tgt;
-       int logo_issued;
        int rc;
 
        BNX2FC_IO_DBG(io_req, "cmd_timeout, cmd_type = %d,"
@@ -80,25 +77,14 @@ static void bnx2fc_cmd_timeout(struct work_struct *work)
                                        io_req->refcount.refcount.counter);
                        if (!(test_and_set_bit(BNX2FC_FLAG_ABTS_DONE,
                                               &io_req->req_flags))) {
-
-                               lport = io_req->port->lport;
-                               rdata = io_req->tgt->rdata;
-                               logo_issued = test_and_set_bit(
-                                               BNX2FC_FLAG_EXPL_LOGO,
-                                               &tgt->flags);
+                               /*
+                                * Cleanup and return original command to
+                                * mid-layer.
+                                */
+                               bnx2fc_initiate_cleanup(io_req);
                                kref_put(&io_req->refcount, bnx2fc_cmd_release);
                                spin_unlock_bh(&tgt->tgt_lock);
 
-                               /* Explicitly logo the target */
-                               if (!logo_issued) {
-                                       BNX2FC_IO_DBG(io_req, "Explicit "
-                                                  "logo - tgt flags = 0x%lx\n",
-                                                  tgt->flags);
-
-                                       mutex_lock(&lport->disc.disc_mutex);
-                                       lport->tt.rport_logoff(rdata);
-                                       mutex_unlock(&lport->disc.disc_mutex);
-                               }
                                return;
                        }
                } else {
@@ -116,28 +102,10 @@ static void bnx2fc_cmd_timeout(struct work_struct *work)
                                rc = bnx2fc_initiate_abts(io_req);
                                if (rc == SUCCESS)
                                        goto done;
-                               /*
-                                * Explicitly logo the target if
-                                * abts initiation fails
-                                */
-                               lport = io_req->port->lport;
-                               rdata = io_req->tgt->rdata;
-                               logo_issued = test_and_set_bit(
-                                               BNX2FC_FLAG_EXPL_LOGO,
-                                               &tgt->flags);
+
                                kref_put(&io_req->refcount, bnx2fc_cmd_release);
                                spin_unlock_bh(&tgt->tgt_lock);
 
-                               if (!logo_issued) {
-                                       BNX2FC_IO_DBG(io_req, "Explicit "
-                                                  "logo - tgt flags = 0x%lx\n",
-                                                  tgt->flags);
-
-
-                                       mutex_lock(&lport->disc.disc_mutex);
-                                       lport->tt.rport_logoff(rdata);
-                                       mutex_unlock(&lport->disc.disc_mutex);
-                               }
                                return;
                        } else {
                                BNX2FC_IO_DBG(io_req, "IO already in "
@@ -152,22 +120,9 @@ static void bnx2fc_cmd_timeout(struct work_struct *work)
 
                        if (!test_and_set_bit(BNX2FC_FLAG_ABTS_DONE,
                                              &io_req->req_flags)) {
-                               lport = io_req->port->lport;
-                               rdata = io_req->tgt->rdata;
-                               logo_issued = test_and_set_bit(
-                                               BNX2FC_FLAG_EXPL_LOGO,
-                                               &tgt->flags);
                                kref_put(&io_req->refcount, bnx2fc_cmd_release);
                                spin_unlock_bh(&tgt->tgt_lock);
 
-                               /* Explicitly logo the target */
-                               if (!logo_issued) {
-                                       BNX2FC_IO_DBG(io_req, "Explicitly logo"
-                                                  "(els)\n");
-                                       mutex_lock(&lport->disc.disc_mutex);
-                                       lport->tt.rport_logoff(rdata);
-                                       mutex_unlock(&lport->disc.disc_mutex);
-                               }
                                return;
                        }
                } else {
@@ -1112,18 +1067,11 @@ int bnx2fc_eh_device_reset(struct scsi_cmnd *sc_cmd)
        return bnx2fc_initiate_tmf(sc_cmd, FCP_TMF_LUN_RESET);
 }
 
-int bnx2fc_expl_logo(struct fc_lport *lport, struct bnx2fc_cmd *io_req)
+int bnx2fc_abts_cleanup(struct bnx2fc_cmd *io_req)
 {
        struct bnx2fc_rport *tgt = io_req->tgt;
-       struct fc_rport_priv *rdata = tgt->rdata;
-       int logo_issued;
        int rc = SUCCESS;
-       int wait_cnt = 0;
 
-       BNX2FC_IO_DBG(io_req, "Expl logo - tgt flags = 0x%lx\n",
-                     tgt->flags);
-       logo_issued = test_and_set_bit(BNX2FC_FLAG_EXPL_LOGO,
-                                      &tgt->flags);
        io_req->wait_for_comp = 1;
        bnx2fc_initiate_cleanup(io_req);
 
@@ -1136,21 +1084,8 @@ int bnx2fc_expl_logo(struct fc_lport *lport, struct bnx2fc_cmd *io_req)
         * release the reference taken in eh_abort to allow the
         * target to re-login after flushing IOs
         */
-        kref_put(&io_req->refcount, bnx2fc_cmd_release);
-
-       if (!logo_issued) {
-               clear_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags);
-               mutex_lock(&lport->disc.disc_mutex);
-               lport->tt.rport_logoff(rdata);
-               mutex_unlock(&lport->disc.disc_mutex);
-               do {
-                       msleep(BNX2FC_RELOGIN_WAIT_TIME);
-                       if (wait_cnt++ > BNX2FC_RELOGIN_WAIT_CNT) {
-                               rc = FAILED;
-                               break;
-                       }
-               } while (!test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags));
-       }
+       kref_put(&io_req->refcount, bnx2fc_cmd_release);
+
        spin_lock_bh(&tgt->tgt_lock);
        return rc;
 }
@@ -1252,7 +1187,7 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
                if (cancel_delayed_work(&io_req->timeout_work))
                        kref_put(&io_req->refcount,
                                 bnx2fc_cmd_release); /* drop timer hold */
-               rc = bnx2fc_expl_logo(lport, io_req);
+               rc = bnx2fc_abts_cleanup(io_req);
                /* This only occurs when an task abort was requested while ABTS
                   is in progress.  Setting the IO_CLEANUP flag will skip the
                   RRQ process in the case when the fw generated SCSI_CMD cmpl
@@ -1291,7 +1226,7 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
                /* Let the scsi-ml try to recover this command */
                printk(KERN_ERR PFX "abort failed, xid = 0x%x\n",
                       io_req->xid);
-               rc = bnx2fc_expl_logo(lport, io_req);
+               rc = bnx2fc_abts_cleanup(io_req);
                goto out;
        } else {
                /*
index 30a8788..08ec318 100644 (file)
@@ -560,12 +560,6 @@ void bnx2fc_rport_event_handler(struct fc_lport *lport,
                    (hba->num_ofld_sess == 0)) {
                        wake_up_interruptible(&hba->shutdown_wait);
                }
-               if (test_bit(BNX2FC_FLAG_EXPL_LOGO, &tgt->flags)) {
-                       printk(KERN_ERR PFX "Relogin to the tgt\n");
-                       mutex_lock(&lport->disc.disc_mutex);
-                       lport->tt.rport_login(rdata);
-                       mutex_unlock(&lport->disc.disc_mutex);
-               }
                mutex_unlock(&hba->hba_mutex);
 
                break;