From 8819fac72b9888bec99aae656bcdb1631b99d01b Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Wed, 12 May 2010 12:40:45 -0700 Subject: [PATCH] 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. --- datapath/datapath.c | 20 ++++++++++++-------- datapath/vport-gre.c | 4 ++-- datapath/vport.c | 7 +++---- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/datapath/datapath.c b/datapath/datapath.c index 9fc778be..67c422ad 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 654ead06..bd6d4a3c 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 6b7381e9..cc209593 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) -- 2.30.2