scsi: qla2xxx: Fix Relogin being triggered too fast

Current driver design schedules relogin process via DPC thread every 1
second. In a large fabric, this DPC thread tries to schedule too many
jobs and might get overloaded. As a result of this processing of DPC
thread, it can schedule relogin earlier than 1 second.

Fixes: 726b854870 ("qla2xxx: Add framework for async fabric discovery")
Cc: <stable@vger.kernel.org> # 4.10+
Signed-off-by: Quinn Tran <quinn.tran@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Quinn Tran 2017-12-04 14:45:06 -08:00 committed by Martin K. Petersen
parent 5ef696aa9f
commit 4005a99566
3 changed files with 29 additions and 16 deletions

View File

@ -4110,6 +4110,7 @@ typedef struct scsi_qla_host {
#define LOOP_READY 5
#define LOOP_DEAD 6
unsigned long relogin_jif;
unsigned long dpc_flags;
#define RESET_MARKER_NEEDED 0 /* Send marker to ISP. */
#define RESET_ACTIVE 1

View File

@ -343,15 +343,21 @@ qla2x00_do_dpc_vp(scsi_qla_host_t *vha)
"FCPort update end.\n");
}
if ((test_and_clear_bit(RELOGIN_NEEDED, &vha->dpc_flags)) &&
!test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags) &&
atomic_read(&vha->loop_state) != LOOP_DOWN) {
if (test_bit(RELOGIN_NEEDED, &vha->dpc_flags) &&
!test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags) &&
atomic_read(&vha->loop_state) != LOOP_DOWN) {
ql_dbg(ql_dbg_dpc, vha, 0x4018,
"Relogin needed scheduled.\n");
qla2x00_relogin(vha);
ql_dbg(ql_dbg_dpc, vha, 0x4019,
"Relogin needed end.\n");
if (!vha->relogin_jif ||
time_after_eq(jiffies, vha->relogin_jif)) {
vha->relogin_jif = jiffies + HZ;
clear_bit(RELOGIN_NEEDED, &vha->dpc_flags);
ql_dbg(ql_dbg_dpc, vha, 0x4018,
"Relogin needed scheduled.\n");
qla2x00_relogin(vha);
ql_dbg(ql_dbg_dpc, vha, 0x4019,
"Relogin needed end.\n");
}
}
if (test_and_clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags) &&

View File

@ -4905,7 +4905,7 @@ void qla2x00_relogin(struct scsi_qla_host *vha)
*/
if (atomic_read(&fcport->state) != FCS_ONLINE &&
fcport->login_retry && !(fcport->flags & FCF_ASYNC_SENT)) {
fcport->login_retry--;
if (fcport->flags & FCF_FABRIC_DEVICE) {
ql_dbg(ql_dbg_disc, fcport->vha, 0x2108,
"%s %8phC DS %d LS %d\n", __func__,
@ -4916,6 +4916,7 @@ void qla2x00_relogin(struct scsi_qla_host *vha)
ea.fcport = fcport;
qla2x00_fcport_event_handler(vha, &ea);
} else {
fcport->login_retry--;
status = qla2x00_local_device_login(vha,
fcport);
if (status == QLA_SUCCESS) {
@ -5898,16 +5899,21 @@ qla2x00_do_dpc(void *data)
}
/* Retry each device up to login retry count */
if ((test_and_clear_bit(RELOGIN_NEEDED,
&base_vha->dpc_flags)) &&
if (test_bit(RELOGIN_NEEDED, &base_vha->dpc_flags) &&
!test_bit(LOOP_RESYNC_NEEDED, &base_vha->dpc_flags) &&
atomic_read(&base_vha->loop_state) != LOOP_DOWN) {
ql_dbg(ql_dbg_dpc, base_vha, 0x400d,
"Relogin scheduled.\n");
qla2x00_relogin(base_vha);
ql_dbg(ql_dbg_dpc, base_vha, 0x400e,
"Relogin end.\n");
if (!base_vha->relogin_jif ||
time_after_eq(jiffies, base_vha->relogin_jif)) {
base_vha->relogin_jif = jiffies + HZ;
clear_bit(RELOGIN_NEEDED, &base_vha->dpc_flags);
ql_dbg(ql_dbg_dpc, base_vha, 0x400d,
"Relogin scheduled.\n");
qla2x00_relogin(base_vha);
ql_dbg(ql_dbg_dpc, base_vha, 0x400e,
"Relogin end.\n");
}
}
loop_resync_check:
if (test_and_clear_bit(LOOP_RESYNC_NEEDED,