[PATCH net v3 1/2] net: macb: give reasons for Tx SKB kfree
From: Théo Lebrun <theo.lebrun@bootlin.com>
Date: 2026-06-17 09:17:49
Also in:
lkml, stable
Subsystem:
atmel macb ethernet driver, networking drivers, the rest · Maintainers:
Théo Lebrun, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
Using dev_consume_skb_any() marks the drop reason as SKB_CONSUMED every
time we free a Tx SKB. Instead, replace by SKB_DROP_REASON_NOT_SPECIFIED
when packet has been dropped without sending.
It is not precise but at least differs from SKB_CONSUMED and is used by
many drivers for their error codepaths through dev_kfree_skb_{any,irq}().
Pass a reason around rather than call dev_consume_skb_any() or
dev_kfree_skb_any() because macb_tx_unmap() is called for cleanup in
all cases.
macb_tx_error_task() is made complex because some SKBs encountered have
been successfully sent.
Fixes: 89e5785fc8a6 ("[PATCH] Atmel MACB ethernet driver")
Cc: stable@vger.kernel.org
Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
---
drivers/net/ethernet/cadence/macb_main.c | 24 +++++++++++++++++-------
1 file changed, 17 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index a12aa21244e8..9caae1ef52b1 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c@@ -1201,7 +1201,8 @@ static int macb_halt_tx(struct macb *bp) bp, TSR); } -static void macb_tx_unmap(struct macb *bp, struct macb_tx_skb *tx_skb, int budget) +static void macb_tx_unmap(struct macb *bp, struct macb_tx_skb *tx_skb, + int budget, enum skb_drop_reason reason) { if (tx_skb->mapping) { if (tx_skb->mapped_as_page)
@@ -1214,7 +1215,7 @@ static void macb_tx_unmap(struct macb *bp, struct macb_tx_skb *tx_skb, int budge } if (tx_skb->skb) { - dev_consume_skb_any(tx_skb->skb); + dev_kfree_skb_any_reason(tx_skb->skb, reason); tx_skb->skb = NULL; } }
@@ -1297,7 +1298,8 @@ static void macb_tx_error_task(struct work_struct *work) * Free transmit buffers in upper layer. */ for (tail = queue->tx_tail; tail != queue->tx_head; tail++) { - u32 ctrl; + enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED; + u32 ctrl; desc = macb_tx_desc(queue, tail); ctrl = desc->ctrl;
@@ -1307,7 +1309,10 @@ static void macb_tx_error_task(struct work_struct *work) if (ctrl & MACB_BIT(TX_USED)) { /* skb is set for the last buffer of the frame */ while (!skb) { - macb_tx_unmap(bp, tx_skb, 0); + /* The reason parameter is unused because it + * only matters when skb is valid. + */ + macb_tx_unmap(bp, tx_skb, 0, SKB_CONSUMED); tail++; tx_skb = macb_tx_skb(queue, tail); skb = tx_skb->skb;
@@ -1326,6 +1331,7 @@ static void macb_tx_error_task(struct work_struct *work) bp->dev->stats.tx_bytes += skb->len; queue->stats.tx_bytes += skb->len; bytes += skb->len; + reason = SKB_CONSUMED; } } else { /* "Buffers exhausted mid-frame" errors may only happen
@@ -1339,7 +1345,7 @@ static void macb_tx_error_task(struct work_struct *work) desc->ctrl = ctrl | MACB_BIT(TX_USED); } - macb_tx_unmap(bp, tx_skb, 0); + macb_tx_unmap(bp, tx_skb, 0, reason); } netdev_tx_completed_queue(netdev_get_tx_queue(bp->dev, queue_index),
@@ -1458,7 +1464,7 @@ static int macb_tx_complete(struct macb_queue *queue, int budget) } /* Now we can safely release resources */ - macb_tx_unmap(bp, tx_skb, budget); + macb_tx_unmap(bp, tx_skb, budget, SKB_CONSUMED); /* skb is set only for the last buffer of the frame. * WARNING: at this point skb has been freed by
@@ -2357,7 +2363,11 @@ static unsigned int macb_tx_map(struct macb *bp, for (i = queue->tx_head; i != tx_head; i++) { tx_skb = macb_tx_skb(queue, i); - macb_tx_unmap(bp, tx_skb, 0); + /* The reason parameter is unused, tx_skb->skb has not yet + * been assigned. Parent caller is responsible for freeing + * the SKB. + */ + macb_tx_unmap(bp, tx_skb, 0, SKB_DROP_REASON_NOT_SPECIFIED); } return -ENOMEM;
--
2.54.0