From 3fca849c965333f387aa02dca02326ce3abd1305 Mon Sep 17 00:00:00 2001 From: Przemek Kitszel Date: Fri, 25 Sep 2026 15:15:43 +0200 Subject: [PATCH] ice: skip stats handling for channel VSIs on rebuild ice_vsi_alloc_stat_arrays() returns early for ICE_VSI_CHNL, so a channel VSI never gets an entry in pf->vsi_stats[]. ice_vsi_realloc_stat_arrays() dereferences that entry unconditionally, and ice_vsi_rebuild() calls it before anything else, so the NULL is not filtered out anywhere. The path is live. ice_prepare_for_reset() removes the queue channels only for resets other than a PFR, so a PFR leaves the channel VSIs in place, and ice_rebuild() then calls ice_rebuild_channels(), which rebuilds every ICE_VSI_CHNL VSI it finds. A PF reset with ADQ (mqprio hardware offload) configured thus dereferences NULL. That combination is reset recovery on top of an active mqprio offload, which is why it went unnoticed. It was found while refactoring this code, not reported by a user. I'm leaning towards removing our limited (compared to OOT ADQ) support, but it's outside of this series. Bug could be triggered by: tc qdisc del dev "$IF" root 2>/dev/null || true tc qdisc add dev "$IF" root mqprio num_tc 2 \ map 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 \ queues 2@0 2@2 hw 1 mode channel sleep 3 ethtool --reset "$IF" irq dma filter offload Workqueue: ice ice_service_task [ice] RIP: 0010:ice_vsi_rebuild+0x289/0x380 [ice] ice_rebuild_channels+0xd6/0x320 [ice] ice_rebuild+0x4f6/0x540 [ice] ice_do_reset+0x9f/0x1a0 [ice] ice_service_task+0x4a/0x460 [ice] Fixes: 5995ef88e3a8 ("ice: realloc VSI stats arrays") Signed-off-by: Przemek Kitszel Reviewed-by: Aleksandr Loktionov Link: https://patch.msgid.link/20260925132636.123300-2-przemyslaw.kitszel@intel.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/intel/ice/ice_lib.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c index 9e08db376d3d..31af378aa0e7 100644 --- a/drivers/net/ethernet/intel/ice/ice_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_lib.c @@ -3031,6 +3031,10 @@ ice_vsi_realloc_stat_arrays(struct ice_vsi *vsi) u16 prev_rxq = vsi->alloc_rxq; int i; + /* channel VSIs have no entry in pf->vsi_stats[] */ + if (vsi->type == ICE_VSI_CHNL) + return 0; + vsi_stat = pf->vsi_stats[vsi->idx]; if (req_txq < prev_txq) {