mirror of https://gitee.com/openkylin/linux.git
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:
parent
5ef696aa9f
commit
4005a99566
|
@ -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
|
||||
|
|
|
@ -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) &&
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue