[PATCH net 1/3] net: stmmac: handle partially allocated DMA queues
Maxime Chevallier
maxime.chevallier at bootlin.com
Wed Oct 14 04:36:42 PDT 2026
Hi,
On 10/14/26 08:26, Karl Mehltretter wrote:
> DMA allocation failure unwinds every configured queue, including the
> failed queue and queues not yet allocated. The cleanup helpers then
> dereference buffer arrays that may not exist.
>
> Only traverse allocated buffer arrays. Clear freed pointers because the
> queue structures persist and XDP reconfiguration can reuse them.
>
> Found by inspection. On a BeagleV Ahead (TH1520), fault injection at
> the RX buffer metadata and TX DMA metadata allocations reached these
> invalid cleanup paths before a test guard stopped them. With this
> change, cleanup completed without the guard.
>
> Fixes: 54139cf3bb33 ("net: stmmac: adding multiple buffers for rx")
> Fixes: ce736788e8a9 ("net: stmmac: adding multiple buffers for TX")
> Assisted-by: LLM
> Signed-off-by: Karl Mehltretter <kmehltretter at gmail.com>
Please look at https://lore.kernel.org/netdev/20261012142458.2845385-1-dinghui1111@163.com/ .
LLMs keep finding the same bugs again and again, make sure you ask
it if there isn't already an in-flight patch for it before sending it :)
Maxime
> ---
> .../net/ethernet/stmicro/stmmac/stmmac_main.c | 22 ++++++++++++++-----
> 1 file changed, 17 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index b837e8e27..495ff7aef 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -2144,10 +2144,12 @@ static void __free_dma_rx_desc_resources(struct stmmac_priv *priv,
> void *addr;
>
> /* Release the DMA RX socket buffers */
> - if (rx_q->xsk_pool)
> - dma_free_rx_xskbufs(priv, dma_conf, queue);
> - else
> - dma_free_rx_skbufs(priv, dma_conf, queue);
> + if (rx_q->buf_pool) {
> + if (rx_q->xsk_pool)
> + dma_free_rx_xskbufs(priv, dma_conf, queue);
> + else
> + dma_free_rx_skbufs(priv, dma_conf, queue);
> + }
>
> rx_q->buf_alloc_num = 0;
> rx_q->xsk_pool = NULL;
> @@ -2161,13 +2163,17 @@ static void __free_dma_rx_desc_resources(struct stmmac_priv *priv,
> size = stmmac_get_rx_desc_size(priv) * dma_conf->dma_rx_size;
>
> dma_free_coherent(priv->device, size, addr, rx_q->dma_rx_phy);
> + rx_q->dma_erx = NULL;
> + rx_q->dma_rx = NULL;
>
> if (xdp_rxq_info_is_reg(&rx_q->xdp_rxq))
> xdp_rxq_info_unreg(&rx_q->xdp_rxq);
>
> kfree(rx_q->buf_pool);
> + rx_q->buf_pool = NULL;
> if (rx_q->page_pool)
> page_pool_destroy(rx_q->page_pool);
> + rx_q->page_pool = NULL;
> }
>
> static void free_dma_rx_desc_resources(struct stmmac_priv *priv,
> @@ -2196,7 +2202,8 @@ static void __free_dma_tx_desc_resources(struct stmmac_priv *priv,
> void *addr;
>
> /* Release the DMA TX socket buffers */
> - dma_free_tx_skbufs(priv, dma_conf, queue);
> + if (tx_q->tx_skbuff_dma && tx_q->tx_skbuff)
> + dma_free_tx_skbufs(priv, dma_conf, queue);
>
> if (priv->extend_desc) {
> addr = tx_q->dma_etx;
> @@ -2209,9 +2216,14 @@ static void __free_dma_tx_desc_resources(struct stmmac_priv *priv,
> size = stmmac_get_tx_desc_size(priv, tx_q) * dma_conf->dma_tx_size;
>
> dma_free_coherent(priv->device, size, addr, tx_q->dma_tx_phy);
> + tx_q->dma_etx = NULL;
> + tx_q->dma_entx = NULL;
> + tx_q->dma_tx = NULL;
>
> kfree(tx_q->tx_skbuff_dma);
> + tx_q->tx_skbuff_dma = NULL;
> kfree(tx_q->tx_skbuff);
> + tx_q->tx_skbuff = NULL;
> }
>
> static void free_dma_tx_desc_resources(struct stmmac_priv *priv,
More information about the linux-arm-kernel
mailing list