From: Jesse Gross Date: Wed, 12 May 2010 18:40:58 +0000 (-0700) Subject: datapath: Disable bottom-halves where necessary. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1c075d0aff8267b05073971211e79d73392078cf;p=openvswitch datapath: Disable bottom-halves where necessary. Places that update per-cpu stats without locking need to have bottom halves disabled. Otherwise we can be running in process context and in the middle of an operation and be interrupted by a softirq. --- diff --git a/datapath/datapath.c b/datapath/datapath.c index 165f0a99..9fc778be 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -830,9 +830,10 @@ dp_output_control(struct datapath *dp, struct sk_buff *skb, int queue_no, err_kfree_skb: kfree_skb(skb); err: - stats = percpu_ptr(dp->stats_percpu, get_cpu()); + local_bh_disable(); + stats = per_cpu_ptr(dp->stats_percpu, smp_processor_id()); stats->n_lost++; - put_cpu(); + local_bh_enable(); return err; } diff --git a/datapath/vport-internal_dev.c b/datapath/vport-internal_dev.c index d23b4c3e..88d3444c 100644 --- a/datapath/vport-internal_dev.c +++ b/datapath/vport-internal_dev.c @@ -11,10 +11,8 @@ #include #include #include -#include #include #include -#include #include "datapath.h" #include "openvswitch/internal_dev.h" @@ -81,8 +79,7 @@ static int internal_dev_mac_addr(struct net_device *dev, void *p) return 0; } -/* Not reentrant (because it is called with BHs disabled), but may be called - * simultaneously on different CPUs. */ +/* Called with rcu_read_lock and bottom-halves disabled. */ static int internal_dev_xmit(struct sk_buff *skb, struct net_device *netdev) { struct internal_dev *internal_dev = internal_dev_priv(netdev); @@ -101,9 +98,7 @@ static int internal_dev_xmit(struct sk_buff *skb, struct net_device *netdev) skb_reset_mac_header(skb); compute_ip_summed(skb, true); - rcu_read_lock_bh(); vport_receive(vport, skb); - rcu_read_unlock_bh(); return 0; } @@ -340,11 +335,11 @@ internal_dev_recv(struct vport *vport, struct sk_buff *skb) netif_rx_ni(skb); netdev->last_rx = jiffies; - preempt_disable(); + local_bh_disable(); lb_stats = per_cpu_ptr(internal_dev->lstats, smp_processor_id()); lb_stats->rx_packets++; lb_stats->rx_bytes += len; - preempt_enable(); + local_bh_enable(); return len; }