macvlan: cleanup rx statistics
authorArnd Bergmann <arnd@arndb.de>
Thu, 26 Nov 2009 06:07:09 +0000 (06:07 +0000)
committerDavid S. Miller <davem@davemloft.net>
Thu, 26 Nov 2009 23:53:02 +0000 (15:53 -0800)
We have very similar code for rx statistics in
two places in the macvlan driver, with a third
one being added in the next patch.

Consolidate them into one function to improve
overall readability of the driver.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/macvlan.c

index ae2b5c79c55e73295b5daaffd6e6f1d13a4236f3..1e7faf9e87b2105b7a8f9126961abe69a2785dfc 100644 (file)
@@ -116,42 +116,58 @@ static int macvlan_addr_busy(const struct macvlan_port *port,
        return 0;
 }
 
+static inline void macvlan_count_rx(const struct macvlan_dev *vlan,
+                                   unsigned int len, bool success,
+                                   bool multicast)
+{
+       struct macvlan_rx_stats *rx_stats;
+
+       rx_stats = per_cpu_ptr(vlan->rx_stats, smp_processor_id());
+       if (likely(success)) {
+               rx_stats->rx_packets++;;
+               rx_stats->rx_bytes += len;
+               if (multicast)
+                       rx_stats->multicast++;
+       } else {
+               rx_stats->rx_errors++;
+       }
+}
+
+static int macvlan_broadcast_one(struct sk_buff *skb, struct net_device *dev,
+                                const struct ethhdr *eth)
+{
+       if (!skb)
+               return NET_RX_DROP;
+
+       skb->dev = dev;
+       if (!compare_ether_addr_64bits(eth->h_dest,
+                                      dev->broadcast))
+               skb->pkt_type = PACKET_BROADCAST;
+       else
+               skb->pkt_type = PACKET_MULTICAST;
+
+       return netif_rx(skb);
+}
+
 static void macvlan_broadcast(struct sk_buff *skb,
                              const struct macvlan_port *port)
 {
        const struct ethhdr *eth = eth_hdr(skb);
        const struct macvlan_dev *vlan;
        struct hlist_node *n;
-       struct net_device *dev;
        struct sk_buff *nskb;
        unsigned int i;
-       struct macvlan_rx_stats *rx_stats;
+       int err;
 
        if (skb->protocol == htons(ETH_P_PAUSE))
                return;
 
        for (i = 0; i < MACVLAN_HASH_SIZE; i++) {
                hlist_for_each_entry_rcu(vlan, n, &port->vlan_hash[i], hlist) {
-                       dev = vlan->dev;
-                       rx_stats = per_cpu_ptr(vlan->rx_stats, smp_processor_id());
-
                        nskb = skb_clone(skb, GFP_ATOMIC);
-                       if (nskb == NULL) {
-                               rx_stats->rx_errors++;
-                               continue;
-                       }
-
-                       rx_stats->rx_bytes += skb->len + ETH_HLEN;
-                       rx_stats->rx_packets++;
-                       rx_stats->multicast++;
-
-                       nskb->dev = dev;
-                       if (!compare_ether_addr_64bits(eth->h_dest, dev->broadcast))
-                               nskb->pkt_type = PACKET_BROADCAST;
-                       else
-                               nskb->pkt_type = PACKET_MULTICAST;
-
-                       netif_rx(nskb);
+                       err = macvlan_broadcast_one(nskb, vlan->dev, eth);
+                       macvlan_count_rx(vlan, skb->len + ETH_HLEN,
+                                        err == NET_RX_SUCCESS, 1);
                }
        }
 }
@@ -163,7 +179,7 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
        const struct macvlan_port *port;
        const struct macvlan_dev *vlan;
        struct net_device *dev;
-       struct macvlan_rx_stats *rx_stats;
+       unsigned int len;
 
        port = rcu_dereference(skb->dev->macvlan_port);
        if (port == NULL)
@@ -183,15 +199,11 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
                kfree_skb(skb);
                return NULL;
        }
-       rx_stats = per_cpu_ptr(vlan->rx_stats, smp_processor_id());
+       len = skb->len + ETH_HLEN;
        skb = skb_share_check(skb, GFP_ATOMIC);
-       if (skb == NULL) {
-               rx_stats->rx_errors++;
+       macvlan_count_rx(vlan, len, skb != NULL, 0);
+       if (!skb)
                return NULL;
-       }
-
-       rx_stats->rx_bytes += skb->len + ETH_HLEN;
-       rx_stats->rx_packets++;
 
        skb->dev = dev;
        skb->pkt_type = PACKET_HOST;