From f14a6832fcd25ec95b102552cfe8d331946f1fc7 Mon Sep 17 00:00:00 2001 From: Ingo Molnar 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 Signed-off-by: Thomas Gleixner Signed-off-by: Paul Gortmaker --- 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