RE: [PATCH iwl-net] ice: fix infinite recursion in ice_cfg_tx_topo via ice_init_dev_hw

From: Loktionov, Aleksandr

Date: Tue Apr 14 2026 - 04:44:17 EST




> -----Original Message-----
> From: Petr Oros <poros@xxxxxxxxxx>
> Sent: Monday, April 13, 2026 9:14 PM
> To: netdev@xxxxxxxxxxxxxxx
> Cc: Oros, Petr <poros@xxxxxxxxxx>; Nguyen, Anthony L
> <anthony.l.nguyen@xxxxxxxxx>; Kitszel, Przemyslaw
> <przemyslaw.kitszel@xxxxxxxxx>; Andrew Lunn <andrew+netdev@xxxxxxx>;
> David S. Miller <davem@xxxxxxxxxxxxx>; Eric Dumazet
> <edumazet@xxxxxxxxxx>; Jakub Kicinski <kuba@xxxxxxxxxx>; Paolo Abeni
> <pabeni@xxxxxxxxxx>; Loktionov, Aleksandr
> <aleksandr.loktionov@xxxxxxxxx>; Nikolay Aleksandrov
> <razor@xxxxxxxxxxxxx>; Daniel Zahka <daniel.zahka@xxxxxxxxx>;
> Greenwalt, Paul <paul.greenwalt@xxxxxxxxx>; Ertman, David M
> <david.m.ertman@xxxxxxxxx>; Michal Swiatkowski
> <michal.swiatkowski@xxxxxxxxxxxxxxx>; Keller, Jacob E
> <jacob.e.keller@xxxxxxxxx>; intel-wired-lan@xxxxxxxxxxxxxxxx; linux-
> kernel@xxxxxxxxxxxxxxx
> Subject: [PATCH iwl-net] ice: fix infinite recursion in
> ice_cfg_tx_topo via ice_init_dev_hw
>
> On certain E810 configurations where firmware supports Tx scheduler
> topology switching (tx_sched_topo_comp_mode_en), ice_cfg_tx_topo() may
> need to apply a new 5-layer or 9-layer topology from the DDP package.
> If the AQ command to set the topology fails (e.g. due to invalid DDP
> data or firmware limitations), the global configuration lock must
> still be cleared via a CORER reset.
>
> Commit 86aae43f21cf ("ice: don't leave device non-functional if Tx
> scheduler config fails") correctly fixed this by refactoring
> ice_cfg_tx_topo() to always trigger CORER after acquiring the global
> lock and re-initialize hardware via ice_init_hw() afterwards.
>
> However, commit 8a37f9e2ff40 ("ice: move ice_deinit_dev() to the end
> of deinit paths") later moved ice_init_dev_hw() into ice_init_hw(),
> breaking the reinit path introduced by 86aae43f21cf. This creates an
> infinite recursive call chain:
>
> ice_init_hw()
> ice_init_dev_hw()
> ice_cfg_tx_topo() # topology change needed
> ice_deinit_hw()
> ice_init_hw() # reinit after CORER
> ice_init_dev_hw() # recurse
> ice_cfg_tx_topo()
> ... # stack overflow
>
> Fix by moving ice_init_dev_hw() back out of ice_init_hw() and calling
> it explicitly from ice_probe() and ice_devlink_reinit_up(). The third
> caller, ice_cfg_tx_topo(), intentionally does not need
> ice_init_dev_hw() during its reinit, it only needs the core HW
> reinitialization. This breaks the recursion cleanly without adding
> flags or guards.
>
> The deinit ordering changes from commit 8a37f9e2ff40 ("ice: move
> ice_deinit_dev() to the end of deinit paths") which fixed slow rmmod
> are preserved, only the init-side placement of ice_init_dev_hw() is
> reverted.
>
> Fixes: 8a37f9e2ff40 ("ice: move ice_deinit_dev() to the end of deinit
> paths")
> Signed-off-by: Petr Oros <poros@xxxxxxxxxx>
> ---
> drivers/net/ethernet/intel/ice/devlink/devlink.c | 2 ++
> drivers/net/ethernet/intel/ice/ice_common.c | 2 --
> drivers/net/ethernet/intel/ice/ice_main.c | 2 ++
> 3 files changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/ice/devlink/devlink.c
> b/drivers/net/ethernet/intel/ice/devlink/devlink.c
> index 6144cee8034d77..641d6e289d5ce6 100644
> --- a/drivers/net/ethernet/intel/ice/devlink/devlink.c
> +++ b/drivers/net/ethernet/intel/ice/devlink/devlink.c
> @@ -1245,6 +1245,8 @@ static int ice_devlink_reinit_up(struct ice_pf
> *pf)
> return err;
> }
>
> + ice_init_dev_hw(pf);
> +
> /* load MSI-X values */
> ice_set_min_max_msix(pf);
>
> diff --git a/drivers/net/ethernet/intel/ice/ice_common.c
> b/drivers/net/ethernet/intel/ice/ice_common.c
> index ce11fea122d03e..b617a6bff89134 100644
> --- a/drivers/net/ethernet/intel/ice/ice_common.c
> +++ b/drivers/net/ethernet/intel/ice/ice_common.c
> @@ -1126,8 +1126,6 @@ int ice_init_hw(struct ice_hw *hw)
> if (status)
> goto err_unroll_fltr_mgmt_struct;
>
> - ice_init_dev_hw(hw->back);
> -
> mutex_init(&hw->tnl_lock);
> ice_init_chk_recipe_reuse_support(hw);
>
> diff --git a/drivers/net/ethernet/intel/ice/ice_main.c
> b/drivers/net/ethernet/intel/ice/ice_main.c
> index e2a5534819d194..a27be29f9bbbfc 100644
> --- a/drivers/net/ethernet/intel/ice/ice_main.c
> +++ b/drivers/net/ethernet/intel/ice/ice_main.c
> @@ -5314,6 +5314,8 @@ ice_probe(struct pci_dev *pdev, const struct
> pci_device_id __always_unused *ent)
> return err;
> }
>
> + ice_init_dev_hw(pf);
> +
> adapter = ice_adapter_get(pdev);
> if (IS_ERR(adapter)) {
> err = PTR_ERR(adapter);
> --
> 2.52.0

Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@xxxxxxxxx>