One option would be to cover this extra condition in enetc_free_tx_ring(), but now that the ENETC_TX_DOWN exists, we have created a window at the beginning of enetc_stop() where NAPI can still be scheduled, but any concurrent enqueue will be blocked. Therefore, enetc_wait_bdrs() and enetc_disable_tx_bdrs() can be called with NAPI still scheduled, and it is guaranteed that this will not wait indefinitely, but instead give us an indication that the pending TX frames have orderly dropped to zero. Only then should we call napi_disable(). This way, enetc_free_tx_ring() becomes entirely redundant and can be dropped as part of subsequent cleanup. The change also refactors enetc_start() so that it looks like the mirror opposite procedure of enetc_stop(). Fixes: ff58fda09096 ("net: enetc: prioritize ability to go down over packet processing") Cc: stable@xxxxxxxxxxxxxxx Signed-off-by: Wei Fang <wei.fang@xxxxxxx> Reviewed-by: Vladimir Oltean <vladimir.oltean@xxxxxxx> Tested-by: Vladimir Oltean <vladimir.oltean@xxxxxxx> Link: https://patch.msgid.link/20241010092056.298128-5-wei.fang@xxxxxxx Signed-off-by: Jakub Kicinski <kuba@xxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- drivers/net/ethernet/freescale/enetc/enetc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) --- a/drivers/net/ethernet/freescale/enetc/enetc.c +++ b/drivers/net/ethernet/freescale/enetc/enetc.c @@ -2477,8 +2477,6 @@ void enetc_start(struct net_device *ndev enetc_setup_interrupts(priv); - enetc_enable_tx_bdrs(priv); - for (i = 0; i < priv->bdr_int_num; i++) { int irq = pci_irq_vector(priv->si->pdev, ENETC_BDR_INT_BASE_IDX + i); @@ -2487,6 +2485,8 @@ void enetc_start(struct net_device *ndev enable_irq(irq); } + enetc_enable_tx_bdrs(priv); + enetc_enable_rx_bdrs(priv); netif_tx_start_all_queues(ndev); @@ -2555,6 +2555,10 @@ void enetc_stop(struct net_device *ndev) enetc_disable_rx_bdrs(priv); + enetc_wait_bdrs(priv); + + enetc_disable_tx_bdrs(priv); + for (i = 0; i < priv->bdr_int_num; i++) { int irq = pci_irq_vector(priv->si->pdev, ENETC_BDR_INT_BASE_IDX + i); @@ -2564,10 +2568,6 @@ void enetc_stop(struct net_device *ndev) napi_disable(&priv->int_vector[i]->napi); } - enetc_wait_bdrs(priv); - - enetc_disable_tx_bdrs(priv); - enetc_clear_interrupts(priv); } EXPORT_SYMBOL_GPL(enetc_stop); Patches currently in stable-queue which might be from wei.fang@xxxxxxx are queue-6.11/net-enetc-disable-tx-bd-rings-after-they-are-empty.patch queue-6.11/net-enetc-remove-xdp_drops-statistic-from-enetc_xdp_drop.patch queue-6.11/net-enetc-add-missing-static-descriptor-and-inline-keyword.patch queue-6.11/net-enetc-disable-napi-after-all-rings-are-disabled.patch queue-6.11/net-enetc-block-concurrent-xdp-transmissions-during-ring-reconfiguration.patch