Message ID | 20241008132402.26164-2-a.kovaleva@yadro.com |
---|---|
State | New |
Headers | show |
Series | Fix bugs in qla2xxx driver | expand |
On 10/8/24 15:24, Anastasia Kovaleva wrote: > Long-lived sessions under high load can accumulate a starvation counter, > and the current implementation does not allow this counter to be reset > during an active session. > > If HBA sends correct ATIO IOCB, then it has enough resources to process > commands and we should not call ISP recovery. > > Cc: stable@vger.kernel.org > Fixes: ead038556f64 ("qla2xxx: Add Dual mode support in the driver") > Signed-off-by: Anastasia Kovaleva <a.kovaleva@yadro.com> > Reviewed-by: Dmitry Bogdanov <d.bogdanov@yadro.com> > --- > drivers/scsi/qla2xxx/qla_isr.c | 4 ++++ > drivers/scsi/qla2xxx/qla_target.c | 11 +++++++++++ > 2 files changed, 15 insertions(+) > > diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c > index fe98c76e9be3..5234ce0985e0 100644 > --- a/drivers/scsi/qla2xxx/qla_isr.c > +++ b/drivers/scsi/qla2xxx/qla_isr.c > @@ -1959,6 +1959,10 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb) > ql_dbg(ql_dbg_async, vha, 0x5091, "Transceiver Removal\n"); > break; > > + case MBA_REJECTED_FCP_CMD: > + ql_dbg(ql_dbg_async, vha, 0x5092, "LS_RJT was sent. No resources to process the ELS request.\n"); > + break; > + > default: > ql_dbg(ql_dbg_async, vha, 0x5057, > "Unknown AEN:%04x %04x %04x %04x\n", > diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c > index d7551b1443e4..bc7feef6ee79 100644 > --- a/drivers/scsi/qla2xxx/qla_target.c > +++ b/drivers/scsi/qla2xxx/qla_target.c > @@ -6801,6 +6801,7 @@ qlt_24xx_process_atio_queue(struct scsi_qla_host *vha, uint8_t ha_locked) > struct qla_hw_data *ha = vha->hw; > struct atio_from_isp *pkt; > int cnt, i; > + unsigned long flags = 0; > > if (!ha->flags.fw_started) > return; > @@ -6826,6 +6827,16 @@ qlt_24xx_process_atio_queue(struct scsi_qla_host *vha, uint8_t ha_locked) > qlt_send_term_exchange(ha->base_qpair, NULL, pkt, > ha_locked, 0); > } else { > + /* > + * If we get correct ATIO, then HBA had enough memory > + * to proceed without reset. > + */ > + if (!ha_locked) > + spin_lock_irqsave(&ha->hardware_lock, flags); > + vha->hw->exch_starvation = 0; > + if (!ha_locked) > + spin_unlock_irqrestore(&ha->hardware_lock, flags); > + > qlt_24xx_atio_pkt_all_vps(vha, > (struct atio_from_isp *)pkt, ha_locked); > } Why not just 'WRITE_ONCE()' and drop the spinlock? Cheers, Hannes
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index fe98c76e9be3..5234ce0985e0 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -1959,6 +1959,10 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb) ql_dbg(ql_dbg_async, vha, 0x5091, "Transceiver Removal\n"); break; + case MBA_REJECTED_FCP_CMD: + ql_dbg(ql_dbg_async, vha, 0x5092, "LS_RJT was sent. No resources to process the ELS request.\n"); + break; + default: ql_dbg(ql_dbg_async, vha, 0x5057, "Unknown AEN:%04x %04x %04x %04x\n", diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index d7551b1443e4..bc7feef6ee79 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -6801,6 +6801,7 @@ qlt_24xx_process_atio_queue(struct scsi_qla_host *vha, uint8_t ha_locked) struct qla_hw_data *ha = vha->hw; struct atio_from_isp *pkt; int cnt, i; + unsigned long flags = 0; if (!ha->flags.fw_started) return; @@ -6826,6 +6827,16 @@ qlt_24xx_process_atio_queue(struct scsi_qla_host *vha, uint8_t ha_locked) qlt_send_term_exchange(ha->base_qpair, NULL, pkt, ha_locked, 0); } else { + /* + * If we get correct ATIO, then HBA had enough memory + * to proceed without reset. + */ + if (!ha_locked) + spin_lock_irqsave(&ha->hardware_lock, flags); + vha->hw->exch_starvation = 0; + if (!ha_locked) + spin_unlock_irqrestore(&ha->hardware_lock, flags); + qlt_24xx_atio_pkt_all_vps(vha, (struct atio_from_isp *)pkt, ha_locked); }