Skip to content

Commit 7db8aa3

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 <[email protected]> Signed-off-by: Sean Anderson <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent f3d761e commit 7db8aa3

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
@@ -1234,11 +1234,12 @@ static int macb_tx_complete(struct macb_queue *queue, int budget)
12341234
{
12351235
struct macb *bp = queue->bp;
12361236
u16 queue_index = queue - bp->queues;
1237+
unsigned long flags;
12371238
unsigned int tail;
12381239
unsigned int head;
12391240
int packets = 0;
12401241

1241-
spin_lock(&queue->tx_ptr_lock);
1242+
spin_lock_irqsave(&queue->tx_ptr_lock, flags);
12421243
head = queue->tx_head;
12431244
for (tail = queue->tx_tail; tail != head && packets < budget; tail++) {
12441245
struct macb_tx_skb *tx_skb;
@@ -1297,7 +1298,7 @@ static int macb_tx_complete(struct macb_queue *queue, int budget)
12971298
CIRC_CNT(queue->tx_head, queue->tx_tail,
12981299
bp->tx_ring_size) <= MACB_TX_WAKEUP_THRESH(bp))
12991300
netif_wake_subqueue(bp->dev, queue_index);
1300-
spin_unlock(&queue->tx_ptr_lock);
1301+
spin_unlock_irqrestore(&queue->tx_ptr_lock, flags);
13011302

13021303
return packets;
13031304
}
@@ -1713,8 +1714,9 @@ static void macb_tx_restart(struct macb_queue *queue)
17131714
{
17141715
struct macb *bp = queue->bp;
17151716
unsigned int head_idx, tbqp;
1717+
unsigned long flags;
17161718

1717-
spin_lock(&queue->tx_ptr_lock);
1719+
spin_lock_irqsave(&queue->tx_ptr_lock, flags);
17181720

17191721
if (queue->tx_head == queue->tx_tail)
17201722
goto out_tx_ptr_unlock;
@@ -1726,27 +1728,28 @@ static void macb_tx_restart(struct macb_queue *queue)
17261728
if (tbqp == head_idx)
17271729
goto out_tx_ptr_unlock;
17281730

1729-
spin_lock_irq(&bp->lock);
1731+
spin_lock(&bp->lock);
17301732
macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART));
1731-
spin_unlock_irq(&bp->lock);
1733+
spin_unlock(&bp->lock);
17321734

17331735
out_tx_ptr_unlock:
1734-
spin_unlock(&queue->tx_ptr_lock);
1736+
spin_unlock_irqrestore(&queue->tx_ptr_lock, flags);
17351737
}
17361738

17371739
static bool macb_tx_complete_pending(struct macb_queue *queue)
17381740
{
17391741
bool retval = false;
1742+
unsigned long flags;
17401743

1741-
spin_lock(&queue->tx_ptr_lock);
1744+
spin_lock_irqsave(&queue->tx_ptr_lock, flags);
17421745
if (queue->tx_head != queue->tx_tail) {
17431746
/* Make hw descriptor updates visible to CPU */
17441747
rmb();
17451748

17461749
if (macb_tx_desc(queue, queue->tx_tail)->ctrl & MACB_BIT(TX_USED))
17471750
retval = true;
17481751
}
1749-
spin_unlock(&queue->tx_ptr_lock);
1752+
spin_unlock_irqrestore(&queue->tx_ptr_lock, flags);
17501753
return retval;
17511754
}
17521755

@@ -2314,6 +2317,7 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
23142317
struct macb_queue *queue = &bp->queues[queue_index];
23152318
unsigned int desc_cnt, nr_frags, frag_size, f;
23162319
unsigned int hdrlen;
2320+
unsigned long flags;
23172321
bool is_lso;
23182322
netdev_tx_t ret = NETDEV_TX_OK;
23192323

@@ -2374,7 +2378,7 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
23742378
desc_cnt += DIV_ROUND_UP(frag_size, bp->max_tx_length);
23752379
}
23762380

2377-
spin_lock_bh(&queue->tx_ptr_lock);
2381+
spin_lock_irqsave(&queue->tx_ptr_lock, flags);
23782382

23792383
/* This is a hard error, log it. */
23802384
if (CIRC_SPACE(queue->tx_head, queue->tx_tail,
@@ -2396,15 +2400,15 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
23962400
wmb();
23972401
skb_tx_timestamp(skb);
23982402

2399-
spin_lock_irq(&bp->lock);
2403+
spin_lock(&bp->lock);
24002404
macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART));
2401-
spin_unlock_irq(&bp->lock);
2405+
spin_unlock(&bp->lock);
24022406

24032407
if (CIRC_SPACE(queue->tx_head, queue->tx_tail, bp->tx_ring_size) < 1)
24042408
netif_stop_subqueue(dev, queue_index);
24052409

24062410
unlock:
2407-
spin_unlock_bh(&queue->tx_ptr_lock);
2411+
spin_unlock_irqrestore(&queue->tx_ptr_lock, flags);
24082412

24092413
return ret;
24102414
}

0 commit comments

Comments
 (0)