Commit 113dc07d authored by Andrew Morton's avatar Andrew Morton Committed by David S. Miller

[NET]: Loopback, allocate per-cpu stats statically and fix cpu refcounting.

Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarDavid S. Miller <davem@redhat.com>
parent 6d6b21c5
......@@ -55,8 +55,9 @@
#include <linux/if_arp.h> /* For ARPHRD_ETHER */
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/percpu.h>
static struct net_device_stats *loopback_stats;
static DEFINE_PER_CPU(struct net_device_stats, loopback_stats);
#define LOOPBACK_OVERHEAD (128 + MAX_HEADER + 16 + 16)
......@@ -124,6 +125,7 @@ static void emulate_large_send_offload(struct sk_buff *skb)
*/
static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct net_device_stats *lb_stats;
skb_orphan(skb);
......@@ -142,13 +144,13 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
}
dev->last_rx = jiffies;
if (likely(loopback_stats)) {
get_cpu_ptr(loopback_stats)->rx_bytes += skb->len;
get_cpu_ptr(loopback_stats)->tx_bytes += skb->len;
get_cpu_ptr(loopback_stats)->rx_packets++;
get_cpu_ptr(loopback_stats)->tx_packets++;
put_cpu_ptr(loopback_stats);
}
lb_stats = &per_cpu(loopback_stats, get_cpu());
lb_stats->rx_bytes += skb->len;
lb_stats->tx_bytes += skb->len;
lb_stats->rx_packets++;
lb_stats->tx_packets++;
put_cpu();
netif_rx(skb);
......@@ -165,17 +167,18 @@ static struct net_device_stats *get_stats(struct net_device *dev)
}
memset(stats, 0, sizeof(struct net_device_stats));
if (!loopback_stats) {
return stats;
}
for (i=0; i < NR_CPUS; i++) {
struct net_device_stats *lb_stats;
if (!cpu_possible(i))
continue;
stats->rx_bytes += per_cpu_ptr(loopback_stats, i)->rx_bytes;
stats->tx_bytes += per_cpu_ptr(loopback_stats, i)->tx_bytes;
stats->rx_packets += per_cpu_ptr(loopback_stats, i)->rx_packets;
stats->tx_packets += per_cpu_ptr(loopback_stats, i)->tx_packets;
lb_stats = &per_cpu(loopback_stats, get_cpu());
stats->rx_bytes += lb_stats->rx_bytes;
stats->tx_bytes += lb_stats->tx_bytes;
stats->rx_packets += lb_stats->rx_packets;
stats->tx_packets += lb_stats->tx_packets;
put_cpu();
}
return stats;
......@@ -211,8 +214,6 @@ int __init loopback_init(void)
loopback_dev.priv = stats;
loopback_dev.get_stats = &get_stats;
}
loopback_stats = alloc_percpu(struct net_device_stats);
return register_netdev(&loopback_dev);
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment