Skip to content

Commit

Permalink
loopback: packet drops accounting
Browse files Browse the repository at this point in the history
We can in some situations drop packets in netif_rx()

loopback driver does not report these (unlikely) drops to its stats,
and incorrectly change packets/bytes counts.

After this patch applied, "ifconfig lo" can reports these drops as in :

# ifconfig lo
lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:692562900 errors:3228 dropped:3228 overruns:0 frame:0
          TX packets:692562900 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:2865674174 (2.6 GiB)  TX bytes:2865674174 (2.6 GiB)

I initialy chose to reflect those errors only in tx_dropped/tx_errors, but David
convinced me that it was really RX errors, as loopback_xmit() really starts
a RX process. (calling eth_type_trans() for example, that itself pulls the ethernet header)

These errors are accounted in rx_dropped/rx_errors.

Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Eric Dumazet authored and David S. Miller committed Apr 20, 2009
1 parent eb62efd commit 7eebb0b
Showing 1 changed file with 15 additions and 6 deletions.
21 changes: 15 additions & 6 deletions drivers/net/loopback.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
struct pcpu_lstats {
unsigned long packets;
unsigned long bytes;
unsigned long drops;
};

/*
Expand All @@ -71,18 +72,22 @@ struct pcpu_lstats {
static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct pcpu_lstats *pcpu_lstats, *lb_stats;
int len;

skb_orphan(skb);

skb->protocol = eth_type_trans(skb,dev);
skb->protocol = eth_type_trans(skb, dev);

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

netif_rx(skb);
len = skb->len;
if (likely(netif_rx(skb) == NET_RX_SUCCESS)) {
lb_stats->bytes += len;
lb_stats->packets++;
} else
lb_stats->drops++;

return 0;
}
Expand All @@ -93,6 +98,7 @@ static struct net_device_stats *loopback_get_stats(struct net_device *dev)
struct net_device_stats *stats = &dev->stats;
unsigned long bytes = 0;
unsigned long packets = 0;
unsigned long drops = 0;
int i;

pcpu_lstats = dev->ml_priv;
Expand All @@ -102,11 +108,14 @@ static struct net_device_stats *loopback_get_stats(struct net_device *dev)
lb_stats = per_cpu_ptr(pcpu_lstats, i);
bytes += lb_stats->bytes;
packets += lb_stats->packets;
drops += lb_stats->drops;
}
stats->rx_packets = packets;
stats->tx_packets = packets;
stats->rx_bytes = bytes;
stats->tx_bytes = bytes;
stats->rx_dropped = drops;
stats->rx_errors = drops;
stats->rx_bytes = bytes;
stats->tx_bytes = bytes;
return stats;
}

Expand Down

0 comments on commit 7eebb0b

Please sign in to comment.