From: Pravin B Shelar Date: Fri, 7 Oct 2011 02:45:09 +0000 (-0700) Subject: datapath: Fix recv path for CONFIG_PREEMPT_RCU. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8a5d84f621f23ea2594248410641c037e9bc919d;p=openvswitch 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 Acked-by: Jesse Gross --- diff --git a/datapath/vport-internal_dev.c b/datapath/vport-internal_dev.c index ecfb3793..1c6897f4 100644 --- a/datapath/vport-internal_dev.c +++ b/datapath/vport-internal_dev.c @@ -68,7 +68,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))) { @@ -79,7 +79,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; }