Skip to content

Commit c0fd0fe

Browse files
Eric-Terminalkuba-moo
authored andcommitted
net: ftgmac100: fix ring allocation unwind on open failure
ftgmac100_alloc_rings() allocates rx_skbs, tx_skbs, rxdes, txdes, and rx_scratch in stages. On intermediate failures it returned -ENOMEM directly, leaking resources allocated earlier in the function. Rework the failure path to use staged local unwind labels and free allocated resources in reverse order before returning -ENOMEM. This matches common netdev allocation cleanup style. Fixes: d72e01a ("ftgmac100: Use a scratch buffer for failed RX allocations") Cc: stable@vger.kernel.org Signed-off-by: Yufan Chen <yufan.chen@linux.dev> Link: https://patch.msgid.link/20260328163257.60836-1-yufan.chen@linux.dev Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 5dd8025 commit c0fd0fe

1 file changed

Lines changed: 24 additions & 4 deletions

File tree

drivers/net/ethernet/faraday/ftgmac100.c

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -977,29 +977,49 @@ static int ftgmac100_alloc_rings(struct ftgmac100 *priv)
977977
priv->tx_skbs = kcalloc(MAX_TX_QUEUE_ENTRIES, sizeof(void *),
978978
GFP_KERNEL);
979979
if (!priv->tx_skbs)
980-
return -ENOMEM;
980+
goto err_free_rx_skbs;
981981

982982
/* Allocate descriptors */
983983
priv->rxdes = dma_alloc_coherent(priv->dev,
984984
MAX_RX_QUEUE_ENTRIES * sizeof(struct ftgmac100_rxdes),
985985
&priv->rxdes_dma, GFP_KERNEL);
986986
if (!priv->rxdes)
987-
return -ENOMEM;
987+
goto err_free_tx_skbs;
988988
priv->txdes = dma_alloc_coherent(priv->dev,
989989
MAX_TX_QUEUE_ENTRIES * sizeof(struct ftgmac100_txdes),
990990
&priv->txdes_dma, GFP_KERNEL);
991991
if (!priv->txdes)
992-
return -ENOMEM;
992+
goto err_free_rxdes;
993993

994994
/* Allocate scratch packet buffer */
995995
priv->rx_scratch = dma_alloc_coherent(priv->dev,
996996
RX_BUF_SIZE,
997997
&priv->rx_scratch_dma,
998998
GFP_KERNEL);
999999
if (!priv->rx_scratch)
1000-
return -ENOMEM;
1000+
goto err_free_txdes;
10011001

10021002
return 0;
1003+
1004+
err_free_txdes:
1005+
dma_free_coherent(priv->dev,
1006+
MAX_TX_QUEUE_ENTRIES *
1007+
sizeof(struct ftgmac100_txdes),
1008+
priv->txdes, priv->txdes_dma);
1009+
priv->txdes = NULL;
1010+
err_free_rxdes:
1011+
dma_free_coherent(priv->dev,
1012+
MAX_RX_QUEUE_ENTRIES *
1013+
sizeof(struct ftgmac100_rxdes),
1014+
priv->rxdes, priv->rxdes_dma);
1015+
priv->rxdes = NULL;
1016+
err_free_tx_skbs:
1017+
kfree(priv->tx_skbs);
1018+
priv->tx_skbs = NULL;
1019+
err_free_rx_skbs:
1020+
kfree(priv->rx_skbs);
1021+
priv->rx_skbs = NULL;
1022+
return -ENOMEM;
10031023
}
10041024

10051025
static void ftgmac100_init_rings(struct ftgmac100 *priv)

0 commit comments

Comments
 (0)