summaryrefslogtreecommitdiffstats
path: root/drivers-net-Make-loopback_xmit-rt-safe.patch
blob: a7a86dc25c33a6d2991699eea7b9efaeeacf85ad (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
From f14a6832fcd25ec95b102552cfe8d331946f1fc7 Mon Sep 17 00:00:00 2001
From: Ingo Molnar <mingo@elte.hu>
Date: Fri, 3 Jul 2009 08:29:30 -0500
Subject: [PATCH] drivers/net: Make loopback_xmit -rt safe

commit cc78f78d74928e7752e70fdfc16e30b8e97a91b7 in tip.

commit 58f539740b ([NET]: Can use __get_cpu_var() instead of per_cpu()
in loopback driver.) breaks on preempt-rt.

Use get_cpu() if -rt is enabled.

Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
 drivers/net/loopback.c |   19 ++++++++++++++-----
 1 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index 72b7949..377144f 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -65,6 +65,14 @@ struct pcpu_lstats {
 	unsigned long drops;
 };
 
+#ifdef CONFIG_PREEMPT_RT
+# define xmit_get_cpu()		get_cpu()
+# define xmit_put_cpu()		put_cpu()
+#else
+# define xmit_get_cpu()		smp_processor_id()
+# define xmit_put_cpu()		do { } while (0)
+#endif
+
 /*
  * The higher levels take care of making this non-reentrant (it's
  * called with bh's disabled).
@@ -74,23 +82,24 @@ static netdev_tx_t loopback_xmit(struct sk_buff *skb,
 {
 	struct pcpu_lstats __percpu *pcpu_lstats;
 	struct pcpu_lstats *lb_stats;
-	int len;
+	int len, res;
 
 	skb_orphan(skb);
 
 	skb->protocol = eth_type_trans(skb, dev);
+	len = skb->len;
+	res = netif_rx(skb);
 
-	/* it's OK to use per_cpu_ptr() because BHs are off */
 	pcpu_lstats = (void __percpu __force *)dev->ml_priv;
-	lb_stats = this_cpu_ptr(pcpu_lstats);
+	lb_stats = per_cpu_ptr(pcpu_lstats, xmit_get_cpu());
 
-	len = skb->len;
-	if (likely(netif_rx(skb) == NET_RX_SUCCESS)) {
+	if (likely(res == NET_RX_SUCCESS)) {
 		lb_stats->bytes += len;
 		lb_stats->packets++;
 	} else
 		lb_stats->drops++;
 
+	xmit_put_cpu();
 	return NETDEV_TX_OK;
 }
 
-- 
1.7.0.4