Re: [PATCH 5.10.y 2/6] net: macb: use NAPI for TX completion path
Robert Hancock <[email protected]>
| Newsgroups | org.kernel.vger.stable |
|---|---|
| Message-ID | <[email protected]> |
On Wed, 2026-07-29 at 12:57 -0400, Sasha Levin wrote: > From: Robert Hancock <[email protected]> > > [ Upstream commit 138badbc21a0113ce783270c426210d6451da5d1 ] FYI, just seeing this now - it appears this patch has been cherry- picked or rebased in some faulty way, as it no longer matches the commit description. In its current form, it seems like it would either do nothing or possibly cause regressions. Same with the 5.15.y version of this patch. > > This driver was using the TX IRQ handler to perform all TX completion > tasks. Under heavy TX network load, this can cause significant irqs- > off > latencies (found to be in the hundreds of microseconds using ftrace). > This can cause other issues, such as overrunning serial UART FIFOs > when > using high baud rates with limited UART FIFO sizes. > > Switch to using a NAPI poll handler to perform the TX completion work > to get this out of hard IRQ context and avoid the IRQ latency impact. > A > separate NAPI instance is used for TX and RX to avoid checking the > other > ring's state unnecessarily when doing the poll, and so that the NAPI > budget handling can work for both TX and RX packets. > > A new per-queue tx_ptr_lock spinlock has been added to avoid using > the > main device lock (with IRQs needing to be disabled) across the entire > TX > mapping operation, and also to protect the TX queue pointers from > concurrent access between the TX start and TX poll operations. > > The TX Used Bit Read interrupt (TXUBR) handling also needs to be > moved into > the TX NAPI poll handler to maintain the proper order of operations. > A flag > is used to notify the poll handler that a UBR condition needs to be > handled. The macb_tx_restart handler has had some locking added for > global > register access, since this could now potentially happen concurrently > on > different queues. > > Signed-off-by: Robert Hancock <[email protected]> > Signed-off-by: Jakub Kicinski <[email protected]> > Stable-dep-of: 27f575836cfe ("net: macb: drop in-flight Tx SKBs on > close") > Signed-off-by: Sasha Levin <[email protected]> > --- > drivers/net/ethernet/cadence/macb_main.c | 12 ++++++------ > 1 file changed, 6 insertions(+), 6 deletions(-) > > diff --git a/drivers/net/ethernet/cadence/macb_main.c > b/drivers/net/ethernet/cadence/macb_main.c > index 3dbef49b17668c..b116d6778f8f90 100644 > --- a/drivers/net/ethernet/cadence/macb_main.c > +++ b/drivers/net/ethernet/cadence/macb_main.c > @@ -837,7 +837,7 @@ static int macb_halt_tx(struct macb *bp) > bp, TSR); > } > > -static void macb_tx_unmap(struct macb *bp, struct macb_tx_skb > *tx_skb) > +static void macb_tx_unmap(struct macb *bp, struct macb_tx_skb > *tx_skb, int budget) > { > if (tx_skb->mapping) { > if (tx_skb->mapped_as_page) > @@ -850,7 +850,7 @@ static void macb_tx_unmap(struct macb *bp, struct > macb_tx_skb *tx_skb) > } > > if (tx_skb->skb) { > - dev_kfree_skb_any(tx_skb->skb); > + napi_consume_skb(tx_skb->skb, budget); > tx_skb->skb = NULL; > } > } > @@ -940,7 +940,7 @@ 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); > + macb_tx_unmap(bp, tx_skb, 0); > tail++; > tx_skb = macb_tx_skb(queue, tail); > skb = tx_skb->skb; > @@ -970,7 +970,7 @@ static void macb_tx_error_task(struct work_struct > *work) > desc->ctrl = ctrl | MACB_BIT(TX_USED); > } > > - macb_tx_unmap(bp, tx_skb); > + macb_tx_unmap(bp, tx_skb, 0); > } > > /* Set end of TX queue */ > @@ -1064,7 +1064,7 @@ static void macb_tx_interrupt(struct macb_queue > *queue) > } > > /* Now we can safely release resources */ > - macb_tx_unmap(bp, tx_skb); > + macb_tx_unmap(bp, tx_skb, 0); > > /* skb is set only for the last buffer of the > frame. > * WARNING: at this point skb has been freed > by > @@ -1903,7 +1903,7 @@ 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); > + macb_tx_unmap(bp, tx_skb, 0); > } > > return 0; > -- > 2.53.0