Message ID | 20220308082048.9774-9-njavali@marvell.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | qla2xxx driver fixes | expand |
> On Mar 8, 2022, at 12:20 AM, Nilesh Javali <njavali@marvell.com> wrote: > > From: Quinn Tran <qutran@marvell.com> > > For session recovery, driver relies on the dpc thread to > initiate certain operation. The dpc thread runs exclusively > without the Mailbox interface being occupied. Recent code change > for heartbeat check via mailbox cmd 0 is causing 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. > > Cc: stable@vger.kernel.org > Fixes: d94d8158e184 ("scsi: qla2xxx: Add heartbeat check") > Signed-off-by: Quinn Tran <qutran@marvell.com> > Signed-off-by: Nilesh Javali <njavali@marvell.com> > --- > drivers/scsi/qla2xxx/qla_def.h | 1 + > drivers/scsi/qla2xxx/qla_os.c | 20 +++++++++++++++++--- > 2 files changed, 18 insertions(+), 3 deletions(-) > > diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h > index b0579bce5b88..80b02b077753 100644 > --- a/drivers/scsi/qla2xxx/qla_def.h > +++ b/drivers/scsi/qla2xxx/qla_def.h > @@ -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; > diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c > index d572a76d0fa0..89c7ac36a41a 100644 > --- a/drivers/scsi/qla2xxx/qla_os.c > +++ b/drivers/scsi/qla2xxx/qla_os.c > @@ -7218,7 +7218,7 @@ static bool qla_do_heartbeat(struct scsi_qla_host *vha) > 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; > > @@ -7228,8 +7228,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); > + } > } > > /************************************************************************** > @@ -7420,6 +7431,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) || > @@ -7452,9 +7465,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); > } > -- > 2.19.0.rc0 > Looks Good. Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com> -- Himanshu Madhani Oracle Linux Engineering
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index b0579bce5b88..80b02b077753 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -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; diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index d572a76d0fa0..89c7ac36a41a 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -7218,7 +7218,7 @@ static bool qla_do_heartbeat(struct scsi_qla_host *vha) 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; @@ -7228,8 +7228,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); + } } /************************************************************************** @@ -7420,6 +7431,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) || @@ -7452,9 +7465,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); }