Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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
+15 −9
Original line number Diff line number Diff line
@@ -343,16 +343,22 @@ qla2x00_do_dpc_vp(scsi_qla_host_t *vha)
		    "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) &&
	    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,
			    "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) &&
	    (!(test_and_set_bit(RESET_ACTIVE, &vha->dpc_flags)))) {
+14 −8
Original line number Diff line number Diff line
@@ -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,17 +5899,22 @@ 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) {

			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,
		    &base_vha->dpc_flags)) {