> -----Original Message-----
> From: Kitszel, Przemyslaw <[email protected]>
> Sent: Friday, September 25, 2026 3:16 PM
> To: [email protected]; Jakub Kicinski <[email protected]>
> Cc: Nguyen, Anthony L <[email protected]>; Loktionov,
> Aleksandr <[email protected]>; Schmidt, Michal
> <[email protected]>; [email protected];
> [email protected]; [email protected]; [email protected];
> [email protected]; Kitszel, Przemyslaw
> <[email protected]>
> Subject: [PATCH net v5 5/6] ice: rebuild ring stats arrays instead of
> reallocating them in place
> 
> ice_vsi_realloc_stat_arrays() resized the ring stats arrays in place
> with krealloc_array(), sizing them from vsi->req_txq/req_rxq. That is
> not what ice_vsi_set_num_qs() computes later in ice_vsi_cfg_def(), so
> after a rebuild the arrays could end up shorter than vsi->alloc_txq /
> vsi->alloc_rxq, and ice_vsi_alloc_ring_stats() then walked past their
> end.
> 
> The VF case shows the divergence. ice_sriov_set_msix_vec_count()
> writes
> vsi->req_txq and then calls ice_vsi_rebuild(), so the old resizer
> sized
> from req_txq, while ice_vsi_get_num_qs() reads vf->num_req_qs ?:
> vf->num_vf_qs and ignores req_txq entirely. Once a guest has raised
> vf->num_req_qs through VIRTCHNL_OP_REQUEST_QUEUES the two disagree and
> the arrays come out shorter than the alloc_txq/alloc_rxq the rebuild
> installs. The reset that such a request triggers is a different path,
> ice_vf_reconfig_vsi(), which does not use this resizer at all; that
> one is handled by the next patch.
> 
> Replace it with ice_vsi_resize_stat_arrays(), which allocates a fresh
> struct ice_vsi_stats instead, sized with ice_vsi_get_num_qs() and the
> queues ice_vsi_decfg() is about to return to the PF pool, which is
> exactly what ice_vsi_set_num_qs() will compute once they are back
> there, barring a concurrent change of the PF pool; the next patch
> stops relying on that. Copy the surviving entry pointers over and
> install the new structure, all before ice_vsi_decfg() runs. The
> entries that did not fit are freed by
> ice_vsi_free_unused_stat_arrays(); the old container itself then goes
> through __ice_vsi_free_stats() with @free_entries set to false, since
> the entries it still points at now belong to the new structure.
> 
> Allocating up front also means a failure no longer leaves a half-
> updated ice_vsi_stats behind, with the Tx array already swapped and
> its surplus Tx entries already freed, but the Rx allocation failed.
> 
> Put the allocate-install-free-surplus sequence in
> ice_vsi_install_stat_arrays(), next to ice_vsi_new_stat_arrays(), so
> that only the sizing decision is left in the resizer.
> 
> Signed-off-by: Przemek Kitszel <[email protected]>
> ---
> this removes some tech debt, but it is not independently backportable,
> as it sits on three preceding refactors; the NULL dereference and the
> sizing mismatch are fixed by their own patches, which carry Fixes:
> tags
> 
> v5:
>  - drop the false "requesting fewer queues than the PF pool can hand
>    out" reproducer, use the VF one that the code can exhibit
> (Clashiko)
>  - describe the real failure-path benefit, the old code already
> returned
>    before ice_vsi_decfg() with the VSI fully configured (Clashiko)
>  - split the ICE_VSI_CHNL guard into its own patch with a Fixes: tag
>    (Clashiko)
>  - factor out ice_vsi_install_stat_arrays(), reused by the new sizing
>    patch (Clashiko)
> ---
>  drivers/net/ethernet/intel/ice/ice_lib.c | 144 ++++++++++++++--------
> -
>  1 file changed, 88 insertions(+), 56 deletions(-)
> 
> diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c
> b/drivers/net/ethernet/intel/ice/ice_lib.c
> index 134984077d5d..448d3c7780ad 100644
> --- a/drivers/net/ethernet/intel/ice/ice_lib.c
> +++ b/drivers/net/ethernet/intel/ice/ice_lib.c
> @@ -557,6 +557,80 @@ static struct ice_vsi_stats
> *ice_vsi_new_stat_arrays(int txq, int rxq)
>       return vsi_stat;
>  }
> 

...

>       if (ret)
>               goto unlock;
> 
> --
> 2.51.1

Reviewed-by: Aleksandr Loktionov <[email protected]>

Reply via email to