From 0033640cfa464801b662a322e3377e0172bb9547 Mon Sep 17 00:00:00 2001 From: Gustavo Walbon Date: Tue, 8 May 2018 22:25:28 -0300 Subject: [PATCH][SRU][Bionic 8/9] scsi: qla2xxx: Prevent relogin trigger from sending too many commands BugLink: http://bugs.launchpad.net/bugs/1770003 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 Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen (cherry-picked from 6d67492764b39ad6efb6822816ad73dc141752f4) Signed-off-by: Gustavo Walbon --- drivers/scsi/qla2xxx/qla_def.h | 1 + drivers/scsi/qla2xxx/qla_gs.c | 6 ++++-- drivers/scsi/qla2xxx/qla_init.c | 14 +++++++++----- drivers/scsi/qla2xxx/qla_os.c | 4 +++- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 008321426be4..750734363caa 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2438,6 +2438,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 diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index 985ccfdb92ea..adf5394a844c 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -2881,7 +2881,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; @@ -2990,6 +2990,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); } @@ -3002,6 +3003,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); } @@ -3020,7 +3022,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 */ diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 5ba2946e9034..10bd50c6fce4 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -108,7 +108,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); @@ -156,7 +156,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); @@ -544,7 +545,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); spin_lock(&vha->hw->tgt.sess_lock); - fcport->flags &= ~FCF_ASYNC_SENT; + fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); spin_unlock(&vha->hw->tgt.sess_lock); ea.fcport = fcport; @@ -641,6 +642,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); } @@ -660,7 +662,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); if (res) { rval = res; @@ -794,6 +796,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); } @@ -1433,6 +1436,7 @@ qla24xx_async_abort_cmd(srb_t *cmd_sp) done_free_sp: sp->free(sp); + sp->fcport->flags &= ~FCF_ASYNC_SENT; done: return rval; } diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index e0b65c531bb8..6bed159960b6 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -4643,6 +4643,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); \ } @@ -4954,7 +4955,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__, -- 2.16.0