From: Jesse Gross Date: Wed, 12 May 2010 19:40:45 +0000 (-0700) Subject: datapath: Don't expect bottom-halves to be disabled. X-Git-Tag: v1.0.0~3 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=8819fac72b9888bec99aae656bcdb1631b99d01b;p=sliver-openvswitch.git datapath: Don't expect bottom-halves to be disabled. We currently document that BHs need to be disabled when handling received packets. However, this isn't actually generally the case (usually preemption is disabled but not BHs). Only one place actually relies on BHs being disabled so fix that and update the documentation of our expectations. --- diff --git a/datapath/datapath.c b/datapath/datapath.c index 9fc778bed..67c422adc 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -512,11 +512,12 @@ out: return err; } -/* Must be called with rcu_read_lock and with bottom-halves disabled. */ +/* Must be called with rcu_read_lock. */ void dp_process_received_packet(struct dp_port *p, struct sk_buff *skb) { struct datapath *dp = p->dp; struct dp_stats_percpu *stats; + int stats_counter_off; struct odp_flow_key key; struct tbl_node *flow_node; @@ -525,14 +526,11 @@ void dp_process_received_packet(struct dp_port *p, struct sk_buff *skb) OVS_CB(skb)->dp_port = p; - /* BHs are off so we don't have to use get_cpu()/put_cpu() here. */ - stats = percpu_ptr(dp->stats_percpu, smp_processor_id()); - if (flow_extract(skb, p ? p->port_no : ODPP_NONE, &key)) { if (dp->drop_frags) { kfree_skb(skb); - stats->n_frags++; - return; + stats_counter_off = offsetof(struct dp_stats_percpu, n_frags); + goto out; } } @@ -543,11 +541,17 @@ void dp_process_received_packet(struct dp_port *p, struct sk_buff *skb) flow_used(flow, skb); execute_actions(dp, skb, &key, acts->actions, acts->n_actions, GFP_ATOMIC); - stats->n_hit++; + stats_counter_off = offsetof(struct dp_stats_percpu, n_hit); } else { - stats->n_missed++; + stats_counter_off = offsetof(struct dp_stats_percpu, n_missed); dp_output_control(dp, skb, _ODPL_MISS_NR, OVS_CB(skb)->tun_id); } + +out: + local_bh_disable(); + stats = per_cpu_ptr(dp->stats_percpu, smp_processor_id()); + (*(u64 *)((u8 *)stats + stats_counter_off))++; + local_bh_enable(); } #if defined(CONFIG_XEN) && defined(HAVE_PROTO_DATA_VALID) diff --git a/datapath/vport-gre.c b/datapath/vport-gre.c index 654ead064..bd6d4a3c2 100644 --- a/datapath/vport-gre.c +++ b/datapath/vport-gre.c @@ -735,7 +735,7 @@ handle_csum_offload(struct sk_buff *skb) } } -/* Called with rcu_read_lock and bottom-halves disabled. */ +/* Called with rcu_read_lock. */ static void gre_err(struct sk_buff *skb, u32 info) { @@ -847,7 +847,7 @@ out: skb->protocol = htons(ETH_P_IP); } -/* Called with rcu_read_lock and bottom-halves disabled. */ +/* Called with rcu_read_lock. */ static int gre_rcv(struct sk_buff *skb) { diff --git a/datapath/vport.c b/datapath/vport.c index 6b7381e9f..cc2095937 100644 --- a/datapath/vport.c +++ b/datapath/vport.c @@ -1087,10 +1087,9 @@ vport_get_mtu(const struct vport *vport) * @vport: vport that received the packet * @skb: skb that was received * - * Must be called with rcu_read_lock and bottom halves disabled. The packet - * cannot be shared and skb->data should point to the Ethernet header. The - * caller must have already called compute_ip_summed() to initialize the - * checksumming fields. + * Must be called with rcu_read_lock. The packet cannot be shared and + * skb->data should point to the Ethernet header. The caller must have already + * called compute_ip_summed() to initialize the checksumming fields. */ void vport_receive(struct vport *vport, struct sk_buff *skb)