summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Pfaff <blp@nicira.com>2010-01-13 10:43:31 -0800
committerBen Pfaff <blp@nicira.com>2010-01-13 10:43:31 -0800
commit81eec36e0200a149f7e239b717cdf93378f6107a (patch)
tree609387dab64904495c88531e8eed4b2db44c0c4d
parent78f172aa4ea3acd28085a457059ad82ba2f2c79a (diff)
downloadopenvswitch-81eec36e0200a149f7e239b717cdf93378f6107a.tar.gz
datapath: Disable preemption updating per-CPU data in dp_dev_recv().
dp_dev_recv() is called from do_output(), which can be called from execute_actions(), which can be called from process context with preemption enabled, so it needs to disabled preemption before it can access per-CPU data. Build tested on a few different kernels. Bug #2316. Reported-by: John Galgay <john@galgay.net> CC: Dan Wendlandt <dan@nicira.com>
-rw-r--r--datapath/dp_dev.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/datapath/dp_dev.c b/datapath/dp_dev.c
index 284a6b520..5b434c1f9 100644
--- a/datapath/dp_dev.c
+++ b/datapath/dp_dev.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009 Nicira Networks.
+ * Copyright (c) 2009, 2010 Nicira Networks.
* Distributed under the terms of the GNU GPL version 2.
*
* Significant portions of this file may be copied from parts of the Linux
@@ -10,6 +10,7 @@
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
+#include <linux/preempt.h>
#include <linux/rcupdate.h>
#include <linux/skbuff.h>
#include <linux/workqueue.h>
@@ -62,9 +63,13 @@ int dp_dev_recv(struct net_device *netdev, struct sk_buff *skb)
else
netif_rx_ni(skb);
netdev->last_rx = jiffies;
+
+ preempt_disable();
lb_stats = per_cpu_ptr(dp_dev->lstats, smp_processor_id());
lb_stats->rx_packets++;
lb_stats->rx_bytes += len;
+ preempt_enable();
+
return len;
}