scsi: qla2xxx: Fix laggy FC remote port session recovery
[ Upstream commit 713b415726f100f6644971e75ebfe1edbef1a390 ]
For session recovery, driver relies on the dpc thread to initiate certain
operations. The dpc thread runs exclusively without the Mailbox interface
being occupied. A recent code change for heartbeat check via mailbox cmd 0
is preventing the dpc thread from carrying out its operation. This patch
allows the higher priority error recovery to run first before running the
lower priority heartbeat check.
Link: https://lore.kernel.org/r/20220310092604.22950-9-njavali@marvell.com
Fixes: d94d8158e1 ("scsi: qla2xxx: Add heartbeat check")
Cc: stable@vger.kernel.org
Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
Signed-off-by: Quinn Tran <qutran@marvell.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
241afac69b
commit
d451011991
@@ -4621,6 +4621,7 @@ struct qla_hw_data {
|
||||
struct workqueue_struct *wq;
|
||||
struct work_struct heartbeat_work;
|
||||
struct qlfc_fw fw_buf;
|
||||
unsigned long last_heartbeat_run_jiffies;
|
||||
|
||||
/* FCP_CMND priority support */
|
||||
struct qla_fcp_prio_cfg *fcp_prio_cfg;
|
||||
|
||||
@@ -7205,7 +7205,7 @@ skip:
|
||||
return do_heartbeat;
|
||||
}
|
||||
|
||||
static void qla_heart_beat(struct scsi_qla_host *vha)
|
||||
static void qla_heart_beat(struct scsi_qla_host *vha, u16 dpc_started)
|
||||
{
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
|
||||
@@ -7215,8 +7215,19 @@ static void qla_heart_beat(struct scsi_qla_host *vha)
|
||||
if (vha->hw->flags.eeh_busy || qla2x00_chip_is_down(vha))
|
||||
return;
|
||||
|
||||
if (qla_do_heartbeat(vha))
|
||||
/*
|
||||
* dpc thread cannot run if heartbeat is running at the same time.
|
||||
* We also do not want to starve heartbeat task. Therefore, do
|
||||
* heartbeat task at least once every 5 seconds.
|
||||
*/
|
||||
if (dpc_started &&
|
||||
time_before(jiffies, ha->last_heartbeat_run_jiffies + 5 * HZ))
|
||||
return;
|
||||
|
||||
if (qla_do_heartbeat(vha)) {
|
||||
ha->last_heartbeat_run_jiffies = jiffies;
|
||||
queue_work(ha->wq, &ha->heartbeat_work);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
@@ -7407,6 +7418,8 @@ qla2x00_timer(struct timer_list *t)
|
||||
start_dpc++;
|
||||
}
|
||||
|
||||
/* borrowing w to signify dpc will run */
|
||||
w = 0;
|
||||
/* Schedule the DPC routine if needed */
|
||||
if ((test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
|
||||
test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags) ||
|
||||
@@ -7439,9 +7452,10 @@ qla2x00_timer(struct timer_list *t)
|
||||
test_bit(RELOGIN_NEEDED, &vha->dpc_flags),
|
||||
test_bit(PROCESS_PUREX_IOCB, &vha->dpc_flags));
|
||||
qla2xxx_wake_dpc(vha);
|
||||
w = 1;
|
||||
}
|
||||
|
||||
qla_heart_beat(vha);
|
||||
qla_heart_beat(vha, w);
|
||||
|
||||
qla2x00_restart_timer(vha, WATCH_INTERVAL);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user