Skip to content

Commit a4cb0a1

Browse files
Sean Andersongregkh
authored andcommitted
net: macb: Fix tx_ptr_lock locking
[ Upstream commit 6bc8a50 ] macb_start_xmit and macb_tx_poll can be called with bottom-halves disabled (e.g. from softirq) as well as with interrupts disabled (with netpoll). Because of this, all other functions taking tx_ptr_lock must use spin_lock_irqsave. Fixes: 138badb ("net: macb: use NAPI for TX completion path") Reported-by: Mike Galbraith <efault@gmx.de> Signed-off-by: Sean Anderson <sean.anderson@linux.dev> Link: https://patch.msgid.link/20250829143521.1686062-1-sean.anderson@linux.dev Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 7b77d88 commit a4cb0a1

File tree

1 file changed

+16
-12
lines changed

1 file changed

+16
-12
lines changed

drivers/net/ethernet/cadence/macb_main.c

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,12 +1223,13 @@ static int macb_tx_complete(struct macb_queue *queue, int budget)
12231223
{
12241224
struct macb *bp = queue->bp;
12251225
u16 queue_index = queue - bp->queues;
1226+
unsigned long flags;
12261227
unsigned int tail;
12271228
unsigned int head;
12281229
int packets = 0;
12291230
u32 bytes = 0;
12301231

1231-
spin_lock(&queue->tx_ptr_lock);
1232+
spin_lock_irqsave(&queue->tx_ptr_lock, flags);
12321233
head = queue->tx_head;
12331234
for (tail = queue->tx_tail; tail != head && packets < budget; tail++) {
12341235
struct macb_tx_skb *tx_skb;
@@ -1291,7 +1292,7 @@ static int macb_tx_complete(struct macb_queue *queue, int budget)
12911292
CIRC_CNT(queue->tx_head, queue->tx_tail,
12921293
bp->tx_ring_size) <= MACB_TX_WAKEUP_THRESH(bp))
12931294
netif_wake_subqueue(bp->dev, queue_index);
1294-
spin_unlock(&queue->tx_ptr_lock);
1295+
spin_unlock_irqrestore(&queue->tx_ptr_lock, flags);
12951296

12961297
return packets;
12971298
}
@@ -1707,8 +1708,9 @@ static void macb_tx_restart(struct macb_queue *queue)
17071708
{
17081709
struct macb *bp = queue->bp;
17091710
unsigned int head_idx, tbqp;
1711+
unsigned long flags;
17101712

1711-
spin_lock(&queue->tx_ptr_lock);
1713+
spin_lock_irqsave(&queue->tx_ptr_lock, flags);
17121714

17131715
if (queue->tx_head == queue->tx_tail)
17141716
goto out_tx_ptr_unlock;
@@ -1720,27 +1722,28 @@ static void macb_tx_restart(struct macb_queue *queue)
17201722
if (tbqp == head_idx)
17211723
goto out_tx_ptr_unlock;
17221724

1723-
spin_lock_irq(&bp->lock);
1725+
spin_lock(&bp->lock);
17241726
macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART));
1725-
spin_unlock_irq(&bp->lock);
1727+
spin_unlock(&bp->lock);
17261728

17271729
out_tx_ptr_unlock:
1728-
spin_unlock(&queue->tx_ptr_lock);
1730+
spin_unlock_irqrestore(&queue->tx_ptr_lock, flags);
17291731
}
17301732

17311733
static bool macb_tx_complete_pending(struct macb_queue *queue)
17321734
{
17331735
bool retval = false;
1736+
unsigned long flags;
17341737

1735-
spin_lock(&queue->tx_ptr_lock);
1738+
spin_lock_irqsave(&queue->tx_ptr_lock, flags);
17361739
if (queue->tx_head != queue->tx_tail) {
17371740
/* Make hw descriptor updates visible to CPU */
17381741
rmb();
17391742

17401743
if (macb_tx_desc(queue, queue->tx_tail)->ctrl & MACB_BIT(TX_USED))
17411744
retval = true;
17421745
}
1743-
spin_unlock(&queue->tx_ptr_lock);
1746+
spin_unlock_irqrestore(&queue->tx_ptr_lock, flags);
17441747
return retval;
17451748
}
17461749

@@ -2308,6 +2311,7 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
23082311
struct macb_queue *queue = &bp->queues[queue_index];
23092312
unsigned int desc_cnt, nr_frags, frag_size, f;
23102313
unsigned int hdrlen;
2314+
unsigned long flags;
23112315
bool is_lso;
23122316
netdev_tx_t ret = NETDEV_TX_OK;
23132317

@@ -2368,7 +2372,7 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
23682372
desc_cnt += DIV_ROUND_UP(frag_size, bp->max_tx_length);
23692373
}
23702374

2371-
spin_lock_bh(&queue->tx_ptr_lock);
2375+
spin_lock_irqsave(&queue->tx_ptr_lock, flags);
23722376

23732377
/* This is a hard error, log it. */
23742378
if (CIRC_SPACE(queue->tx_head, queue->tx_tail,
@@ -2392,15 +2396,15 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
23922396
netdev_tx_sent_queue(netdev_get_tx_queue(bp->dev, queue_index),
23932397
skb->len);
23942398

2395-
spin_lock_irq(&bp->lock);
2399+
spin_lock(&bp->lock);
23962400
macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART));
2397-
spin_unlock_irq(&bp->lock);
2401+
spin_unlock(&bp->lock);
23982402

23992403
if (CIRC_SPACE(queue->tx_head, queue->tx_tail, bp->tx_ring_size) < 1)
24002404
netif_stop_subqueue(dev, queue_index);
24012405

24022406
unlock:
2403-
spin_unlock_bh(&queue->tx_ptr_lock);
2407+
spin_unlock_irqrestore(&queue->tx_ptr_lock, flags);
24042408

24052409
return ret;
24062410
}

0 commit comments

Comments
 (0)