summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPravin B Shelar <pshelar@nicira.com>2011-10-06 19:53:23 -0700
committerPravin B Shelar <pshelar@nicira.com>2011-10-06 19:53:23 -0700
commitad48b32f708fcd382af593d2f8c1fff3fbd1db81 (patch)
treea90bcfb6b05a0b487ecbc9e2bbee9beed01db4bc
parent36f9f11036751990cb4ae41799a07dc8a6ffba6c (diff)
downloadopenvswitch-ad48b32f708fcd382af593d2f8c1fff3fbd1db81.tar.gz
datapath: Fix recv path for CONFIG_PREEMPT_RCU.
In case CONFIG_PREEMPT_RCU, rcu grace period waits only for RCU read-side critical sections that are delimited by rcu_read_lock() and rcu_read_unlock(). internal_dev_xmit() is called in rcu_read_lock_bh context. Therefore we need to explicitly take rcu lock to prevent race with call_rcu() in PREEMPT_RCU case. Signed-off-by: Pravin B Shelar <pshelar@nicira.com> Acked-by: Jesse Gross <jesse@nicira.com>
-rw-r--r--datapath/vport-internal_dev.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/datapath/vport-internal_dev.c b/datapath/vport-internal_dev.c
index 5b3b2b3db..45981a87d 100644
--- a/datapath/vport-internal_dev.c
+++ b/datapath/vport-internal_dev.c
@@ -71,7 +71,7 @@ static int internal_dev_mac_addr(struct net_device *dev, void *p)
return 0;
}
-/* Called with rcu_read_lock and bottom-halves disabled. */
+/* Called with rcu_read_lock_bh. */
static int internal_dev_xmit(struct sk_buff *skb, struct net_device *netdev)
{
if (unlikely(compute_ip_summed(skb, true))) {
@@ -82,7 +82,9 @@ static int internal_dev_xmit(struct sk_buff *skb, struct net_device *netdev)
vlan_copy_skb_tci(skb);
OVS_CB(skb)->flow = NULL;
+ rcu_read_lock();
vport_receive(internal_dev_priv(netdev)->vport, skb);
+ rcu_read_unlock();
return 0;
}