| Message ID | 20260923071659.1161191-4-seyeong.kim@canonical.com |
|---|---|
| State | New |
| Headers | show |
| Series | [SRU,R,1/1] RDMA/irdma: Suppress PF reset on HMC error | expand |
Acked-by: Ivan Hu <ivan.hu@canonical.com> On Wed, Sep 23, 2026 at 3:17 PM Seyeong Kim via kernel-team < kernel-team@lists.ubuntu.com> wrote: > BugLink: https://bugs.launchpad.net/bugs/2167995 > > The irdma driver currently issues an unconditional PF reset whenever the > HMC Error interrupt (PFINT_OICR bit 26) fires: > > if (event->reg & IRDMAPFINT_OICR_HMC_ERR_M) { > ibdev_err(&iwdev->ibdev, "HMC Error\n"); > iwdev->rf->reset = true; > } > > request_reset() issues an IIDC_PFR to ice. In practice a single HMC_ERR > can trigger cascading PF resets, IOMMU faults during teardown, and > teardown of every RDMA connection on the device. > > i40e handles the identically-named interrupt by reading > PFHMC_ERRORINFO and PFHMC_ERRORDATA and logging them without touching > device state; see commit 9c010ee0ea5f ("i40e: Suppress HMC error to > Interrupt message level") which removed the reset as "not necessary". > This patch mirrors that handling on irdma. > > With this change, repeated HMC_ERR no longer produces a reset storm and > RDMA traffic on the device continues uninterrupted. > > Signed-off-by: Seyeong Kim <seyeong.kim@canonical.com> > Link: > https://patch.msgid.link/20260619050044.1807044-1-seyeong.kim@canonical.com > Signed-off-by: Leon Romanovsky <leon@kernel.org> > (cherry picked from commit 4dc9c884c0aafac1e8d37536d88d485135e26883) > Signed-off-by: Gerald Yang <gerald.yang@canonical.com> > Signed-off-by: Seyeong Kim <seyeong.kim@canonical.com> > --- > drivers/infiniband/hw/irdma/i40iw_hw.c | 4 +++- > drivers/infiniband/hw/irdma/icrdma_hw.c | 2 ++ > drivers/infiniband/hw/irdma/icrdma_hw.h | 2 ++ > drivers/infiniband/hw/irdma/icrdma_if.c | 8 ++++++-- > drivers/infiniband/hw/irdma/irdma.h | 2 ++ > 5 files changed, 15 insertions(+), 3 deletions(-) > > diff --git a/drivers/infiniband/hw/irdma/i40iw_hw.c > b/drivers/infiniband/hw/irdma/i40iw_hw.c > index 60c1f2b1811d..8301938b4543 100644 > --- a/drivers/infiniband/hw/irdma/i40iw_hw.c > +++ b/drivers/infiniband/hw/irdma/i40iw_hw.c > @@ -29,7 +29,9 @@ static u32 i40iw_regs[IRDMA_MAX_REGS] = { > I40E_PFHMC_PDINV, > I40E_GLHMC_VFPDINV(0), > I40E_GLPE_CRITERR, > - 0xffffffff /* PFINT_RATEN not used in FPK */ > + 0xffffffff, /* PFINT_RATEN not used in FPK */ > + 0xffffffff, /* PFHMC_ERRORINFO not used in FPK */ > + 0xffffffff /* PFHMC_ERRORDATA not used in FPK */ > }; > > static u32 i40iw_stat_offsets[] = { > diff --git a/drivers/infiniband/hw/irdma/icrdma_hw.c > b/drivers/infiniband/hw/irdma/icrdma_hw.c > index 32f26284a788..b1f1b5485762 100644 > --- a/drivers/infiniband/hw/irdma/icrdma_hw.c > +++ b/drivers/infiniband/hw/irdma/icrdma_hw.c > @@ -29,6 +29,8 @@ static u32 icrdma_regs[IRDMA_MAX_REGS] = { > GLHMC_VFPDINV(0), > GLPE_CRITERR, > GLINT_RATE(0), > + PFHMC_ERRORINFO, > + PFHMC_ERRORDATA, > }; > > static u64 icrdma_masks[IRDMA_MAX_MASKS] = { > diff --git a/drivers/infiniband/hw/irdma/icrdma_hw.h > b/drivers/infiniband/hw/irdma/icrdma_hw.h > index d97944ab45da..0acdeda1236d 100644 > --- a/drivers/infiniband/hw/irdma/icrdma_hw.h > +++ b/drivers/infiniband/hw/irdma/icrdma_hw.h > @@ -40,6 +40,8 @@ > #define GLHMC_VFPDINV(_i) (0x00528300 + ((_i) * 4)) /* _i=0...31 */ > #define GLPE_CRITERR 0x00534000 > #define GLINT_RATE(_INT) (0x0015A000 + ((_INT) * 4)) /* _i=0...2047 > */ /* Reset Source: CORER */ > +#define PFHMC_ERRORINFO 0x00520400 > +#define PFHMC_ERRORDATA 0x00520500 > > #define ICRDMA_DB_ADDR_OFFSET (8 * 1024 * 1024 - 64 * 1024) > > diff --git a/drivers/infiniband/hw/irdma/icrdma_if.c > b/drivers/infiniband/hw/irdma/icrdma_if.c > index 2172a2092e3f..4b451d8482a4 100644 > --- a/drivers/infiniband/hw/irdma/icrdma_if.c > +++ b/drivers/infiniband/hw/irdma/icrdma_if.c > @@ -91,8 +91,12 @@ static void icrdma_iidc_event_handler(struct > iidc_rdma_core_dev_info *cdev_info, > } > } > if (event->reg & IRDMAPFINT_OICR_HMC_ERR_M) { > - ibdev_err(&iwdev->ibdev, "HMC Error\n"); > - iwdev->rf->reset = true; > + u32 hmc_errinfo = > readl(iwdev->rf->sc_dev.hw_regs[IRDMA_PFHMC_ERRORINFO]); > + u32 hmc_errdata = > readl(iwdev->rf->sc_dev.hw_regs[IRDMA_PFHMC_ERRORDATA]); > + > + /* Log diagnostics; do not reset here. */ > + ibdev_warn(&iwdev->ibdev, "HMC Error: > errinfo=0x%08x errdata=0x%08x\n", > + hmc_errinfo, hmc_errdata); > } > if (event->reg & IRDMAPFINT_OICR_PE_PUSH_M) { > ibdev_err(&iwdev->ibdev, "PE Push Error\n"); > diff --git a/drivers/infiniband/hw/irdma/irdma.h > b/drivers/infiniband/hw/irdma/irdma.h > index ff938a01d70c..e8cda27d7854 100644 > --- a/drivers/infiniband/hw/irdma/irdma.h > +++ b/drivers/infiniband/hw/irdma/irdma.h > @@ -66,6 +66,8 @@ enum irdma_registers { > IRDMA_GLHMC_VFPDINV, > IRDMA_GLPE_CRITERR, > IRDMA_GLINT_RATE, > + IRDMA_PFHMC_ERRORINFO, > + IRDMA_PFHMC_ERRORDATA, > IRDMA_MAX_REGS, /* Must be last entry */ > }; > > -- > 2.43.0 > > > -- > kernel-team mailing list > kernel-team@lists.ubuntu.com > https://lists.ubuntu.com/mailman/listinfo/kernel-team >
diff --git a/drivers/infiniband/hw/irdma/i40iw_hw.c b/drivers/infiniband/hw/irdma/i40iw_hw.c index 60c1f2b1811d..8301938b4543 100644 --- a/drivers/infiniband/hw/irdma/i40iw_hw.c +++ b/drivers/infiniband/hw/irdma/i40iw_hw.c @@ -29,7 +29,9 @@ static u32 i40iw_regs[IRDMA_MAX_REGS] = { I40E_PFHMC_PDINV, I40E_GLHMC_VFPDINV(0), I40E_GLPE_CRITERR, - 0xffffffff /* PFINT_RATEN not used in FPK */ + 0xffffffff, /* PFINT_RATEN not used in FPK */ + 0xffffffff, /* PFHMC_ERRORINFO not used in FPK */ + 0xffffffff /* PFHMC_ERRORDATA not used in FPK */ }; static u32 i40iw_stat_offsets[] = { diff --git a/drivers/infiniband/hw/irdma/icrdma_hw.c b/drivers/infiniband/hw/irdma/icrdma_hw.c index 32f26284a788..b1f1b5485762 100644 --- a/drivers/infiniband/hw/irdma/icrdma_hw.c +++ b/drivers/infiniband/hw/irdma/icrdma_hw.c @@ -29,6 +29,8 @@ static u32 icrdma_regs[IRDMA_MAX_REGS] = { GLHMC_VFPDINV(0), GLPE_CRITERR, GLINT_RATE(0), + PFHMC_ERRORINFO, + PFHMC_ERRORDATA, }; static u64 icrdma_masks[IRDMA_MAX_MASKS] = { diff --git a/drivers/infiniband/hw/irdma/icrdma_hw.h b/drivers/infiniband/hw/irdma/icrdma_hw.h index d97944ab45da..0acdeda1236d 100644 --- a/drivers/infiniband/hw/irdma/icrdma_hw.h +++ b/drivers/infiniband/hw/irdma/icrdma_hw.h @@ -40,6 +40,8 @@ #define GLHMC_VFPDINV(_i) (0x00528300 + ((_i) * 4)) /* _i=0...31 */ #define GLPE_CRITERR 0x00534000 #define GLINT_RATE(_INT) (0x0015A000 + ((_INT) * 4)) /* _i=0...2047 */ /* Reset Source: CORER */ +#define PFHMC_ERRORINFO 0x00520400 +#define PFHMC_ERRORDATA 0x00520500 #define ICRDMA_DB_ADDR_OFFSET (8 * 1024 * 1024 - 64 * 1024) diff --git a/drivers/infiniband/hw/irdma/icrdma_if.c b/drivers/infiniband/hw/irdma/icrdma_if.c index 2172a2092e3f..4b451d8482a4 100644 --- a/drivers/infiniband/hw/irdma/icrdma_if.c +++ b/drivers/infiniband/hw/irdma/icrdma_if.c @@ -91,8 +91,12 @@ static void icrdma_iidc_event_handler(struct iidc_rdma_core_dev_info *cdev_info, } } if (event->reg & IRDMAPFINT_OICR_HMC_ERR_M) { - ibdev_err(&iwdev->ibdev, "HMC Error\n"); - iwdev->rf->reset = true; + u32 hmc_errinfo = readl(iwdev->rf->sc_dev.hw_regs[IRDMA_PFHMC_ERRORINFO]); + u32 hmc_errdata = readl(iwdev->rf->sc_dev.hw_regs[IRDMA_PFHMC_ERRORDATA]); + + /* Log diagnostics; do not reset here. */ + ibdev_warn(&iwdev->ibdev, "HMC Error: errinfo=0x%08x errdata=0x%08x\n", + hmc_errinfo, hmc_errdata); } if (event->reg & IRDMAPFINT_OICR_PE_PUSH_M) { ibdev_err(&iwdev->ibdev, "PE Push Error\n"); diff --git a/drivers/infiniband/hw/irdma/irdma.h b/drivers/infiniband/hw/irdma/irdma.h index ff938a01d70c..e8cda27d7854 100644 --- a/drivers/infiniband/hw/irdma/irdma.h +++ b/drivers/infiniband/hw/irdma/irdma.h @@ -66,6 +66,8 @@ enum irdma_registers { IRDMA_GLHMC_VFPDINV, IRDMA_GLPE_CRITERR, IRDMA_GLINT_RATE, + IRDMA_PFHMC_ERRORINFO, + IRDMA_PFHMC_ERRORDATA, IRDMA_MAX_REGS, /* Must be last entry */ };
BugLink: https://bugs.launchpad.net/bugs/2167995 The irdma driver currently issues an unconditional PF reset whenever the HMC Error interrupt (PFINT_OICR bit 26) fires: if (event->reg & IRDMAPFINT_OICR_HMC_ERR_M) { ibdev_err(&iwdev->ibdev, "HMC Error\n"); iwdev->rf->reset = true; } request_reset() issues an IIDC_PFR to ice. In practice a single HMC_ERR can trigger cascading PF resets, IOMMU faults during teardown, and teardown of every RDMA connection on the device. i40e handles the identically-named interrupt by reading PFHMC_ERRORINFO and PFHMC_ERRORDATA and logging them without touching device state; see commit 9c010ee0ea5f ("i40e: Suppress HMC error to Interrupt message level") which removed the reset as "not necessary". This patch mirrors that handling on irdma. With this change, repeated HMC_ERR no longer produces a reset storm and RDMA traffic on the device continues uninterrupted. Signed-off-by: Seyeong Kim <seyeong.kim@canonical.com> Link: https://patch.msgid.link/20260619050044.1807044-1-seyeong.kim@canonical.com Signed-off-by: Leon Romanovsky <leon@kernel.org> (cherry picked from commit 4dc9c884c0aafac1e8d37536d88d485135e26883) Signed-off-by: Gerald Yang <gerald.yang@canonical.com> Signed-off-by: Seyeong Kim <seyeong.kim@canonical.com> --- drivers/infiniband/hw/irdma/i40iw_hw.c | 4 +++- drivers/infiniband/hw/irdma/icrdma_hw.c | 2 ++ drivers/infiniband/hw/irdma/icrdma_hw.h | 2 ++ drivers/infiniband/hw/irdma/icrdma_if.c | 8 ++++++-- drivers/infiniband/hw/irdma/irdma.h | 2 ++ 5 files changed, 15 insertions(+), 3 deletions(-)