datapath: Don't expect bottom-halves to be disabled.
authorJesse Gross <jesse@nicira.com>
Wed, 12 May 2010 19:40:45 +0000 (12:40 -0700)
committerJesse Gross <jesse@nicira.com>
Fri, 14 May 2010 22:10:45 +0000 (15:10 -0700)
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
datapath/vport-gre.c
datapath/vport.c

index 9fc778bed53cb806cc13c22bfd8c956ab18960ef..67c422adc816eb3cc148c4977b6193755322e72c 100644 (file)
@@ -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)
index 654ead064c6e9938327483fc2aa5c94dc91d275b..bd6d4a3c283e8d8ac54f8ff3a789c152445f23a0 100644 (file)
@@ -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)
 {
index 6b7381e9f1f6b1d5351ebd983e8b19fdd131456c..cc20959372eb3f86a1d0b8c0b8dc5074a06e5f4e 100644 (file)
@@ -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)