datapath: Fix recv path for CONFIG_PREEMPT_RCU.
authorPravin B Shelar <pshelar@nicira.com>
Fri, 7 Oct 2011 02:53:23 +0000 (19:53 -0700)
committerPravin B Shelar <pshelar@nicira.com>
Fri, 7 Oct 2011 02:53:23 +0000 (19:53 -0700)
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>
datapath/vport-internal_dev.c

index 5b3b2b3..45981a8 100644 (file)
@@ -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;
 }