--- linux.tmp/drivers/net/loopback.c 2004-06-22 09:00:41.000000000 -0700 +++ linux/drivers/net/loopback.c 2004-06-22 09:06:41.000000000 -0700 @@ -55,8 +55,9 @@ #include /* For ARPHRD_ETHER */ #include #include +#include -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 int loopback_xmit(struct sk_buff *skb, struct net_device *dev) { + struct net_device_stats *lb_stats; skb_orphan(skb); @@ -142,13 +144,12 @@ } 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,19 +166,19 @@ } 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, i); + 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; } - + return stats; } @@ -212,8 +213,6 @@ loopback_dev.get_stats = &get_stats; } - loopback_stats = alloc_percpu(struct net_device_stats); - return register_netdev(&loopback_dev); };