Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 66740
b: refs/heads/master
c: 5f6d88b
h: refs/heads/master
v: v3
  • Loading branch information
Eric W. Biederman authored and David S. Miller committed Oct 10, 2007
1 parent 51fb363 commit bef9f13
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9dd776b6d7b0b85966b6ddd03e2b2aae59012ab1
refs/heads/master: 5f6d88b9149d537f3db0798f7d312be632422e15
32 changes: 28 additions & 4 deletions trunk/drivers/net/loopback.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ struct pcpu_lstats {
unsigned long packets;
unsigned long bytes;
};
static DEFINE_PER_CPU(struct pcpu_lstats, pcpu_lstats);

#define LOOPBACK_OVERHEAD (128 + MAX_HEADER + 16 + 16)

Expand Down Expand Up @@ -134,7 +133,7 @@ static void emulate_large_send_offload(struct sk_buff *skb)
*/
static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct pcpu_lstats *lb_stats;
struct pcpu_lstats *pcpu_lstats, *lb_stats;

skb_orphan(skb);

Expand All @@ -155,7 +154,8 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
dev->last_rx = jiffies;

/* it's OK to use __get_cpu_var() because BHs are off */
lb_stats = &__get_cpu_var(pcpu_lstats);
pcpu_lstats = netdev_priv(dev);
lb_stats = per_cpu_ptr(pcpu_lstats, smp_processor_id());
lb_stats->bytes += skb->len;
lb_stats->packets++;

Expand All @@ -166,15 +166,17 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)

static struct net_device_stats *get_stats(struct net_device *dev)
{
const struct pcpu_lstats *pcpu_lstats;
struct net_device_stats *stats = &dev->stats;
unsigned long bytes = 0;
unsigned long packets = 0;
int i;

pcpu_lstats = netdev_priv(dev);
for_each_possible_cpu(i) {
const struct pcpu_lstats *lb_stats;

lb_stats = &per_cpu(pcpu_lstats, i);
lb_stats = per_cpu_ptr(pcpu_lstats, i);
bytes += lb_stats->bytes;
packets += lb_stats->packets;
}
Expand All @@ -198,6 +200,26 @@ static const struct ethtool_ops loopback_ethtool_ops = {
.get_rx_csum = always_on,
};

static int loopback_dev_init(struct net_device *dev)
{
struct pcpu_lstats *lstats;

lstats = alloc_percpu(struct pcpu_lstats);
if (!lstats)
return -ENOMEM;

dev->priv = lstats;
return 0;
}

static void loopback_dev_free(struct net_device *dev)
{
struct pcpu_lstats *lstats = netdev_priv(dev);

free_percpu(lstats);
free_netdev(dev);
}

/*
* The loopback device is special. There is only one instance and
* it is statically allocated. Don't do this for other devices.
Expand Down Expand Up @@ -225,6 +247,8 @@ static void loopback_setup(struct net_device *dev)
| NETIF_F_LLTX
| NETIF_F_NETNS_LOCAL,
dev->ethtool_ops = &loopback_ethtool_ops;
dev->init = loopback_dev_init;
dev->destructor = loopback_dev_free;
}

/* Setup and register the loopback device. */
Expand Down

0 comments on commit bef9f13

Please sign in to comment.