summaryrefslogtreecommitdiffstats
path: root/drivers-net-fix-livelock-issues.patch
blob: e4bfc617b0ebe94e1e63ef5d35e388330a0e8999 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
From: Thomas Gleixner <tglx@linutronix.de>
Date: Sat, 20 Jun 2009 11:36:54 +0200
Subject: drivers/net: fix livelock issues

Preempt-RT runs into a live lock issue with the NETDEV_TX_LOCKED micro
optimization. The reason is that the softirq thread is rescheduling
itself on that return value. Depending on priorities it starts to
monoplize the CPU and livelock on UP systems.

Remove it.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

---
 drivers/net/ethernet/atheros/atl1c/atl1c_main.c      |    6 +-----
 drivers/net/ethernet/atheros/atl1e/atl1e_main.c      |    3 +--
 drivers/net/ethernet/chelsio/cxgb/sge.c              |    3 +--
 drivers/net/ethernet/neterion/s2io.c                 |    7 +------
 drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c |    6 ++----
 drivers/net/ethernet/tehuti/tehuti.c                 |    9 ++-------
 drivers/net/rionet.c                                 |    6 +-----
 7 files changed, 9 insertions(+), 31 deletions(-)

Index: linux-stable/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
===================================================================
--- linux-stable.orig/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ linux-stable/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -2122,11 +2122,7 @@ static netdev_tx_t atl1c_xmit_frame(stru
 	}
 
 	tpd_req = atl1c_cal_tpd_req(skb);
-	if (!spin_trylock_irqsave(&adapter->tx_lock, flags)) {
-		if (netif_msg_pktdata(adapter))
-			dev_info(&adapter->pdev->dev, "tx locked\n");
-		return NETDEV_TX_LOCKED;
-	}
+	spin_lock_irqsave(&adapter->tx_lock, flags);
 
 	if (atl1c_tpd_avail(adapter, type) < tpd_req) {
 		/* no enough descriptor, just stop queue */
Index: linux-stable/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
===================================================================
--- linux-stable.orig/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
+++ linux-stable/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
@@ -1803,8 +1803,7 @@ static netdev_tx_t atl1e_xmit_frame(stru
 		return NETDEV_TX_OK;
 	}
 	tpd_req = atl1e_cal_tdp_req(skb);
-	if (!spin_trylock_irqsave(&adapter->tx_lock, flags))
-		return NETDEV_TX_LOCKED;
+	spin_lock_irqsave(&adapter->tx_lock, flags);
 
 	if (atl1e_tpd_avail(adapter) < tpd_req) {
 		/* no enough descriptor, just stop queue */
Index: linux-stable/drivers/net/ethernet/chelsio/cxgb/sge.c
===================================================================
--- linux-stable.orig/drivers/net/ethernet/chelsio/cxgb/sge.c
+++ linux-stable/drivers/net/ethernet/chelsio/cxgb/sge.c
@@ -1678,8 +1678,7 @@ static int t1_sge_tx(struct sk_buff *skb
 	struct cmdQ *q = &sge->cmdQ[qid];
 	unsigned int credits, pidx, genbit, count, use_sched_skb = 0;
 
-	if (!spin_trylock(&q->lock))
-		return NETDEV_TX_LOCKED;
+	spin_lock(&q->lock);
 
 	reclaim_completed_tx(sge, q);
 
Index: linux-stable/drivers/net/ethernet/neterion/s2io.c
===================================================================
--- linux-stable.orig/drivers/net/ethernet/neterion/s2io.c
+++ linux-stable/drivers/net/ethernet/neterion/s2io.c
@@ -4088,12 +4088,7 @@ static netdev_tx_t s2io_xmit(struct sk_b
 			[skb->priority & (MAX_TX_FIFOS - 1)];
 	fifo = &mac_control->fifos[queue];
 
-	if (do_spin_lock)
-		spin_lock_irqsave(&fifo->tx_lock, flags);
-	else {
-		if (unlikely(!spin_trylock_irqsave(&fifo->tx_lock, flags)))
-			return NETDEV_TX_LOCKED;
-	}
+	spin_lock_irqsave(&fifo->tx_lock, flags);
 
 	if (sp->config.multiq) {
 		if (__netif_subqueue_stopped(dev, fifo->fifo_no)) {
Index: linux-stable/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
===================================================================
--- linux-stable.orig/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+++ linux-stable/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
@@ -2159,10 +2159,8 @@ static int pch_gbe_xmit_frame(struct sk_
 	struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring;
 	unsigned long flags;
 
-	if (!spin_trylock_irqsave(&tx_ring->tx_lock, flags)) {
-		/* Collision - tell upper layer to requeue */
-		return NETDEV_TX_LOCKED;
-	}
+	spin_lock_irqsave(&tx_ring->tx_lock, flags);
+
 	if (unlikely(!PCH_GBE_DESC_UNUSED(tx_ring))) {
 		netif_stop_queue(netdev);
 		spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
Index: linux-stable/drivers/net/ethernet/tehuti/tehuti.c
===================================================================
--- linux-stable.orig/drivers/net/ethernet/tehuti/tehuti.c
+++ linux-stable/drivers/net/ethernet/tehuti/tehuti.c
@@ -1630,13 +1630,8 @@ static netdev_tx_t bdx_tx_transmit(struc
 	unsigned long flags;
 
 	ENTER;
-	local_irq_save(flags);
-	if (!spin_trylock(&priv->tx_lock)) {
-		local_irq_restore(flags);
-		DBG("%s[%s]: TX locked, returning NETDEV_TX_LOCKED\n",
-		    BDX_DRV_NAME, ndev->name);
-		return NETDEV_TX_LOCKED;
-	}
+
+	spin_lock_irqsave(&priv->tx_lock, flags);
 
 	/* build tx descriptor */
 	BDX_ASSERT(f->m.wptr >= f->m.memsz);	/* started with valid wptr */
Index: linux-stable/drivers/net/rionet.c
===================================================================
--- linux-stable.orig/drivers/net/rionet.c
+++ linux-stable/drivers/net/rionet.c
@@ -178,11 +178,7 @@ static int rionet_start_xmit(struct sk_b
 	unsigned long flags;
 	int add_num = 1;
 
-	local_irq_save(flags);
-	if (!spin_trylock(&rnet->tx_lock)) {
-		local_irq_restore(flags);
-		return NETDEV_TX_LOCKED;
-	}
+	spin_lock_irqsave(&rnet->tx_lock, flags);
 
 	if (is_multicast_ether_addr(eth->h_dest))
 		add_num = nact;