Commit 4005a995 authored by Quinn Tran's avatar Quinn Tran Committed by Martin K. Petersen

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: 726b8548 ("qla2xxx: Add framework for async fabric discovery")
Cc: <stable@vger.kernel.org> # 4.10+
Signed-off-by: default avatarQuinn Tran <quinn.tran@cavium.com>
Signed-off-by: default avatarHimanshu Madhani <himanshu.madhani@cavium.com>
Reviewed-by: default avatarHannes Reinecke <hare@suse.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 5ef696aa
...@@ -4110,6 +4110,7 @@ typedef struct scsi_qla_host { ...@@ -4110,6 +4110,7 @@ typedef struct scsi_qla_host {
#define LOOP_READY 5 #define LOOP_READY 5
#define LOOP_DEAD 6 #define LOOP_DEAD 6
unsigned long relogin_jif;
unsigned long dpc_flags; unsigned long dpc_flags;
#define RESET_MARKER_NEEDED 0 /* Send marker to ISP. */ #define RESET_MARKER_NEEDED 0 /* Send marker to ISP. */
#define RESET_ACTIVE 1 #define RESET_ACTIVE 1
......
...@@ -343,16 +343,22 @@ qla2x00_do_dpc_vp(scsi_qla_host_t *vha) ...@@ -343,16 +343,22 @@ qla2x00_do_dpc_vp(scsi_qla_host_t *vha)
"FCPort update end.\n"); "FCPort update end.\n");
} }
if ((test_and_clear_bit(RELOGIN_NEEDED, &vha->dpc_flags)) && if (test_bit(RELOGIN_NEEDED, &vha->dpc_flags) &&
!test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags) && !test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags) &&
atomic_read(&vha->loop_state) != LOOP_DOWN) { atomic_read(&vha->loop_state) != LOOP_DOWN) {
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, ql_dbg(ql_dbg_dpc, vha, 0x4018,
"Relogin needed scheduled.\n"); "Relogin needed scheduled.\n");
qla2x00_relogin(vha); qla2x00_relogin(vha);
ql_dbg(ql_dbg_dpc, vha, 0x4019, ql_dbg(ql_dbg_dpc, vha, 0x4019,
"Relogin needed end.\n"); "Relogin needed end.\n");
} }
}
if (test_and_clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags) && if (test_and_clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags) &&
(!(test_and_set_bit(RESET_ACTIVE, &vha->dpc_flags)))) { (!(test_and_set_bit(RESET_ACTIVE, &vha->dpc_flags)))) {
......
...@@ -4905,7 +4905,7 @@ void qla2x00_relogin(struct scsi_qla_host *vha) ...@@ -4905,7 +4905,7 @@ void qla2x00_relogin(struct scsi_qla_host *vha)
*/ */
if (atomic_read(&fcport->state) != FCS_ONLINE && if (atomic_read(&fcport->state) != FCS_ONLINE &&
fcport->login_retry && !(fcport->flags & FCF_ASYNC_SENT)) { fcport->login_retry && !(fcport->flags & FCF_ASYNC_SENT)) {
fcport->login_retry--;
if (fcport->flags & FCF_FABRIC_DEVICE) { if (fcport->flags & FCF_FABRIC_DEVICE) {
ql_dbg(ql_dbg_disc, fcport->vha, 0x2108, ql_dbg(ql_dbg_disc, fcport->vha, 0x2108,
"%s %8phC DS %d LS %d\n", __func__, "%s %8phC DS %d LS %d\n", __func__,
...@@ -4916,6 +4916,7 @@ void qla2x00_relogin(struct scsi_qla_host *vha) ...@@ -4916,6 +4916,7 @@ void qla2x00_relogin(struct scsi_qla_host *vha)
ea.fcport = fcport; ea.fcport = fcport;
qla2x00_fcport_event_handler(vha, &ea); qla2x00_fcport_event_handler(vha, &ea);
} else { } else {
fcport->login_retry--;
status = qla2x00_local_device_login(vha, status = qla2x00_local_device_login(vha,
fcport); fcport);
if (status == QLA_SUCCESS) { if (status == QLA_SUCCESS) {
...@@ -5898,17 +5899,22 @@ qla2x00_do_dpc(void *data) ...@@ -5898,17 +5899,22 @@ qla2x00_do_dpc(void *data)
} }
/* Retry each device up to login retry count */ /* Retry each device up to login retry count */
if ((test_and_clear_bit(RELOGIN_NEEDED, if (test_bit(RELOGIN_NEEDED, &base_vha->dpc_flags) &&
&base_vha->dpc_flags)) &&
!test_bit(LOOP_RESYNC_NEEDED, &base_vha->dpc_flags) && !test_bit(LOOP_RESYNC_NEEDED, &base_vha->dpc_flags) &&
atomic_read(&base_vha->loop_state) != LOOP_DOWN) { atomic_read(&base_vha->loop_state) != LOOP_DOWN) {
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, ql_dbg(ql_dbg_dpc, base_vha, 0x400d,
"Relogin scheduled.\n"); "Relogin scheduled.\n");
qla2x00_relogin(base_vha); qla2x00_relogin(base_vha);
ql_dbg(ql_dbg_dpc, base_vha, 0x400e, ql_dbg(ql_dbg_dpc, base_vha, 0x400e,
"Relogin end.\n"); "Relogin end.\n");
} }
}
loop_resync_check: loop_resync_check:
if (test_and_clear_bit(LOOP_RESYNC_NEEDED, if (test_and_clear_bit(LOOP_RESYNC_NEEDED,
&base_vha->dpc_flags)) { &base_vha->dpc_flags)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment