scsi: qla2xxx: Prevent relogin trigger from sending too many commands
authorQuinn Tran <quinn.tran@cavium.com>
Thu, 28 Dec 2017 20:33:41 +0000 (12:33 -0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Thu, 4 Jan 2018 04:41:07 +0000 (23:41 -0500)
This patch adds check for pending work event before queueing
relogin work to prevent redundant work to be active at the
same time.

Signed-off-by: Quinn Tran <quinn.tran@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_gs.c
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_os.c

index 99d2afa520c2e6b7b18a479c1ca15a40e9824399..ac2f340bc1c64ef4d1fc528debea45d419f20dce 100644 (file)
@@ -2454,6 +2454,7 @@ static const char * const port_state_str[] = {
 #define FCF_FCP2_DEVICE                BIT_2
 #define FCF_ASYNC_SENT         BIT_3
 #define FCF_CONF_COMP_SUPPORTED BIT_4
+#define FCF_ASYNC_ACTIVE       BIT_5
 
 /* No loop ID flag. */
 #define FC_NO_LOOP_ID          0x1000
index abc31b983b9302c48b595c195a1de0b62b1de208..546011b1a7659b5a26882c9b7f2a0d8a01421c9f 100644 (file)
@@ -3088,7 +3088,7 @@ static void qla2x00_async_gidpn_sp_done(void *s, int res)
        u8 *id = fcport->ct_desc.ct_sns->p.rsp.rsp.gid_pn.port_id;
        struct event_arg ea;
 
-       fcport->flags &= ~FCF_ASYNC_SENT;
+       fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
 
        memset(&ea, 0, sizeof(ea));
        ea.fcport = fcport;
@@ -3197,6 +3197,7 @@ int qla24xx_post_gidpn_work(struct scsi_qla_host *vha, fc_port_t *fcport)
                return QLA_FUNCTION_FAILED;
 
        e->u.fcport.fcport = fcport;
+       fcport->flags |= FCF_ASYNC_ACTIVE;
        return qla2x00_post_work(vha, e);
 }
 
@@ -3209,6 +3210,7 @@ int qla24xx_post_gpsc_work(struct scsi_qla_host *vha, fc_port_t *fcport)
                return QLA_FUNCTION_FAILED;
 
        e->u.fcport.fcport = fcport;
+       fcport->flags |= FCF_ASYNC_ACTIVE;
        return qla2x00_post_work(vha, e);
 }
 
@@ -3256,7 +3258,7 @@ static void qla24xx_async_gpsc_sp_done(void *s, int res)
            "Async done-%s res %x, WWPN %8phC \n",
            sp->name, res, fcport->port_name);
 
-       fcport->flags &= ~FCF_ASYNC_SENT;
+       fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
 
        if (res == (DID_ERROR << 16)) {
                /* entry status error */
index 93febc177aa7d301891d465e2d3a0ba972057870..956f51e78e5c5b441ce46756449b9a3c602ef5bc 100644 (file)
@@ -109,7 +109,7 @@ qla2x00_async_iocb_timeout(void *data)
                    "Async-%s timeout - hdl=%x portid=%06x %8phC.\n",
                    sp->name, sp->handle, fcport->d_id.b24, fcport->port_name);
 
-               fcport->flags &= ~FCF_ASYNC_SENT;
+               fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
        } else {
                pr_info("Async-%s timeout - hdl=%x.\n",
                    sp->name, sp->handle);
@@ -154,7 +154,8 @@ qla2x00_async_login_sp_done(void *ptr, int res)
        ql_dbg(ql_dbg_disc, vha, 0x20dd,
            "%s %8phC res %d \n", __func__, sp->fcport->port_name, res);
 
-       sp->fcport->flags &= ~FCF_ASYNC_SENT;
+       sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
+
        if (!test_bit(UNLOADING, &vha->dpc_flags)) {
                memset(&ea, 0, sizeof(ea));
                ea.event = FCME_PLOGI_DONE;
@@ -232,7 +233,7 @@ qla2x00_async_logout_sp_done(void *ptr, int res)
        srb_t *sp = ptr;
        struct srb_iocb *lio = &sp->u.iocb_cmd;
 
-       sp->fcport->flags &= ~FCF_ASYNC_SENT;
+       sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
        if (!test_bit(UNLOADING, &sp->vha->dpc_flags))
                qla2x00_post_async_logout_done_work(sp->vha, sp->fcport,
                    lio->u.logio.data);
@@ -665,7 +666,7 @@ qla24xx_async_gnl_sp_done(void *s, int res)
 
        list_for_each_entry_safe(fcport, tf, &h, gnl_entry) {
                list_del_init(&fcport->gnl_entry);
-               fcport->flags &= ~FCF_ASYNC_SENT;
+               fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
                ea.fcport = fcport;
 
                qla2x00_fcport_event_handler(vha, &ea);
@@ -788,6 +789,7 @@ int qla24xx_post_gnl_work(struct scsi_qla_host *vha, fc_port_t *fcport)
                return QLA_FUNCTION_FAILED;
 
        e->u.fcport.fcport = fcport;
+       fcport->flags |= FCF_ASYNC_ACTIVE;
        return qla2x00_post_work(vha, e);
 }
 
@@ -805,7 +807,7 @@ void qla24xx_async_gpdb_sp_done(void *s, int res)
            "Async done-%s res %x, WWPN %8phC mb[1]=%x mb[2]=%x \n",
            sp->name, res, fcport->port_name, mb[1], mb[2]);
 
-       fcport->flags &= ~FCF_ASYNC_SENT;
+       fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
 
        memset(&ea, 0, sizeof(ea));
        ea.event = FCME_GPDB_DONE;
@@ -927,6 +929,7 @@ int qla24xx_post_gpdb_work(struct scsi_qla_host *vha, fc_port_t *fcport, u8 opt)
 
        e->u.fcport.fcport = fcport;
        e->u.fcport.opt = opt;
+       fcport->flags |= FCF_ASYNC_ACTIVE;
        return qla2x00_post_work(vha, e);
 }
 
@@ -1516,6 +1519,7 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint32_t lun,
 
 done_free_sp:
        sp->free(sp);
+       sp->fcport->flags &= ~FCF_ASYNC_SENT;
 done:
        return rval;
 }
index 605100e3c6c6439fd4b9352ad59e7eb0b8e3a28a..a64f67a562f0616965ad83f299379424d39f1fdb 100644 (file)
@@ -4697,6 +4697,7 @@ int qla2x00_post_async_##name##_work(             \
                e->u.logio.data[0] = data[0];   \
                e->u.logio.data[1] = data[1];   \
        }                                       \
+       fcport->flags |= FCF_ASYNC_ACTIVE;      \
        return qla2x00_post_work(vha, e);       \
 }
 
@@ -5076,7 +5077,8 @@ void qla2x00_relogin(struct scsi_qla_host *vha)
                 * to it if we haven't run out of retries.
                 */
                if (atomic_read(&fcport->state) != FCS_ONLINE &&
-                   fcport->login_retry && !(fcport->flags & FCF_ASYNC_SENT)) {
+                   fcport->login_retry &&
+                   !(fcport->flags & (FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE))) {
                        if (vha->hw->current_topology != ISP_CFG_NL) {
                                ql_dbg(ql_dbg_disc, fcport->vha, 0x2108,
                                    "%s %8phC DS %d LS %d\n", __func__,