Commit 138badbc authored by Robert Hancock's avatar Robert Hancock Committed by Jakub Kicinski

net: macb: use NAPI for TX completion path

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: default avatarRobert Hancock <robert.hancock@calian.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 1900e30d
...@@ -1204,11 +1204,15 @@ struct macb_queue { ...@@ -1204,11 +1204,15 @@ struct macb_queue {
unsigned int RBQP; unsigned int RBQP;
unsigned int RBQPH; unsigned int RBQPH;
/* Lock to protect tx_head and tx_tail */
spinlock_t tx_ptr_lock;
unsigned int tx_head, tx_tail; unsigned int tx_head, tx_tail;
struct macb_dma_desc *tx_ring; struct macb_dma_desc *tx_ring;
struct macb_tx_skb *tx_skb; struct macb_tx_skb *tx_skb;
dma_addr_t tx_ring_dma; dma_addr_t tx_ring_dma;
struct work_struct tx_error_task; struct work_struct tx_error_task;
bool txubr_pending;
struct napi_struct napi_tx;
dma_addr_t rx_ring_dma; dma_addr_t rx_ring_dma;
dma_addr_t rx_buffers_dma; dma_addr_t rx_buffers_dma;
...@@ -1217,7 +1221,7 @@ struct macb_queue { ...@@ -1217,7 +1221,7 @@ struct macb_queue {
struct macb_dma_desc *rx_ring; struct macb_dma_desc *rx_ring;
struct sk_buff **rx_skbuff; struct sk_buff **rx_skbuff;
void *rx_buffers; void *rx_buffers;
struct napi_struct napi; struct napi_struct napi_rx;
struct queue_stats stats; struct queue_stats stats;
#ifdef CONFIG_MACB_USE_HWSTAMP #ifdef CONFIG_MACB_USE_HWSTAMP
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment