Re: [PATCH net 1/2] net: enetc: restore RX ring congestion mode after ring reconfiguration
[email protected] Wed, 29 Jul 2026 02:29:16 +0000
| Newsgroups | dev.linux.lists.imx |
|---|---|
| Message-ID | <[email protected]> |
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: Pre-existing issues: - [Critical] Lockless race between phylink's mac_link_up and driver reconfiguration corrupts hardware registers and newly introduced software state, leading to DMA use-after-free and loss of flow control. -- --- Patch [1]: [PATCH net 1/2] net: enetc: restore RX ring congestion mode after ring reconfiguration --- commit 299f421076cc1f539a88e83a486105279c6c0395 Author: Wei Fang <[email protected]> Subject: net: enetc: restore RX ring congestion mode after ring reconfiguration This commit addresses an issue where the RX ring congestion mode is lost during runtime ring reconfiguration. It introduces a software flag to track the congestion mode state and restores it when the RX ring is rebuilt, ensuring flow control continues working. > --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c > +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c > @@ -633,6 +633,8 @@ static void enetc_pl_mac_link_up(struct phylink_config *config, > } > > if (tx_pause) { > + set_bit(ENETC_RXBDR_CM, &priv->flags); > + [Severity: Critical] This is a pre-existing issue, but can this lockless read-modify-write on the ENETC_RBMR register race with driver reconfiguration? Looking at enetc_pl_mac_link_up() in enetc_pf.c, there is an unsynchronized read-modify-write loop on ENETC_RBMR just before this flag update: for (idx = 0; idx < priv->num_rx_rings; idx++) { rbmr = enetc_rxbdr_rd(hw, idx, ENETC_RBMR); ... enetc_rxbdr_wr(hw, idx, ENETC_RBMR, rbmr); } If phylink's mac_link_up executes asynchronously in the phylink_resolve workqueue, could it run concurrently with a user triggering a driver reconfiguration under rtnl_lock (like attaching an XDP program)? If so, enetc_reconfigure() might call enetc_disable_rxbdr(), which clears the ENETC_RBMR register to disable the ring: /* disable EN bit on ring */ enetc_rxbdr_wr(hw, idx, ENETC_RBMR, 0); If mac_link_up() reads the ENETC_RBMR register before it is cleared by reconfiguration, and writes it back after it is cleared, it will write back the stale ENETC_RBMR_EN (enable) bit. Since enetc_reconfigure() proceeds to call enetc_free_rxtx_rings() to free the DMA memory, re-enabling the hardware RX ring at this moment would cause the hardware to DMA incoming network packets into freed kernel memory. Additionally, because the new ENETC_RXBDR_CM software flag is set here after the hardware read-modify-write loop, concurrent readers like enetc_setup_rxbdr() could observe a stale flag state and permanently lose flow control. > /* When the port first enters congestion, send a PAUSE request > * with the maximum number of quanta. When the port exits [ ... ] -- Sashiko AI review ยท https://sashiko.dev/#/patchset/[email protected]?part=1