diff options
author | Ben Pfaff <blp@nicira.com> | 2010-01-13 10:43:31 -0800 |
---|---|---|
committer | Ben Pfaff <blp@nicira.com> | 2010-01-13 10:43:31 -0800 |
commit | 81eec36e0200a149f7e239b717cdf93378f6107a (patch) | |
tree | 609387dab64904495c88531e8eed4b2db44c0c4d | |
parent | 78f172aa4ea3acd28085a457059ad82ba2f2c79a (diff) | |
download | openvswitch-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.c | 7 |
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; } |