mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
net: lan966x: don't disable hardirqs in fdma tx clear path
lan966x_fdma_tx_clear_buf() runs from the NAPI poll and frees the
buffers of completed tx DCBs with napi_consume_skb(),
page_pool_recycle_direct() and xdp_return_frame_bulk(), under
lan966x->tx_lock.
Before this patch, the lock is taken with spin_lock_irqsave(), so the
buffers are freed with hardirqs disabled. RX skbs are marked for
page_pool recycling, so when such an skb is forwarded back out and its
tx completion frees it here, the free path reaches __page_pool_put_page(),
which warns via lockdep_assert_no_hardirq().
Take tx_lock with a plain spin_lock(), as the other tx_lock users,
lan966x_port_xmit() and lan966x_fdma_xmit_xdpf(), already do.
tx_clear_buf() runs from the NAPI poll, so disabling hardirqs there is
not needed.
Found with lockdep enabled (CONFIG_PROVE_LOCKING), which the assert
depends on. Reproduced on a lan9668 board by redirecting received frames
out of another port with tc mirred.
Fixes: 11871aba19 ("net: lan96x: Use page_pool API")
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
Link: https://patch.msgid.link/20261026-lan966x-fdma-tx-clear-hardirq-v1-1-5f70f026a2e4@microchip.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
d54b21d824
commit
b2e17432e7
|
|
@ -336,14 +336,13 @@ static void lan966x_fdma_tx_clear_buf(struct lan966x *lan966x, int weight)
|
|||
struct lan966x_tx_dcb_buf *dcb_buf;
|
||||
struct fdma *fdma = &tx->fdma;
|
||||
struct xdp_frame_bulk bq;
|
||||
unsigned long flags;
|
||||
bool clear = false;
|
||||
struct fdma_db *db;
|
||||
int i;
|
||||
|
||||
xdp_frame_bulk_init(&bq);
|
||||
|
||||
spin_lock_irqsave(&lan966x->tx_lock, flags);
|
||||
spin_lock(&lan966x->tx_lock);
|
||||
for (i = 0; i < fdma->n_dcbs; ++i) {
|
||||
dcb_buf = &tx->dcbs_buf[i];
|
||||
|
||||
|
|
@ -388,7 +387,7 @@ static void lan966x_fdma_tx_clear_buf(struct lan966x *lan966x, int weight)
|
|||
if (clear)
|
||||
lan966x_fdma_wakeup_netdev(lan966x);
|
||||
|
||||
spin_unlock_irqrestore(&lan966x->tx_lock, flags);
|
||||
spin_unlock(&lan966x->tx_lock);
|
||||
}
|
||||
|
||||
static int lan966x_fdma_rx_check_frame(struct lan966x_rx *rx, u64 *src_port)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user