Commit 7eebb0b2 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller

loopback: packet drops accounting

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: default avatarEric Dumazet <dada1@cosmosbay.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent eb62efd2
...@@ -62,6 +62,7 @@ ...@@ -62,6 +62,7 @@
struct pcpu_lstats { struct pcpu_lstats {
unsigned long packets; unsigned long packets;
unsigned long bytes; unsigned long bytes;
unsigned long drops;
}; };
/* /*
...@@ -71,18 +72,22 @@ struct pcpu_lstats { ...@@ -71,18 +72,22 @@ struct pcpu_lstats {
static int loopback_xmit(struct sk_buff *skb, struct net_device *dev) static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
{ {
struct pcpu_lstats *pcpu_lstats, *lb_stats; struct pcpu_lstats *pcpu_lstats, *lb_stats;
int len;
skb_orphan(skb); 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 */ /* it's OK to use per_cpu_ptr() because BHs are off */
pcpu_lstats = dev->ml_priv; pcpu_lstats = dev->ml_priv;
lb_stats = per_cpu_ptr(pcpu_lstats, smp_processor_id()); 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; return 0;
} }
...@@ -93,6 +98,7 @@ static struct net_device_stats *loopback_get_stats(struct net_device *dev) ...@@ -93,6 +98,7 @@ static struct net_device_stats *loopback_get_stats(struct net_device *dev)
struct net_device_stats *stats = &dev->stats; struct net_device_stats *stats = &dev->stats;
unsigned long bytes = 0; unsigned long bytes = 0;
unsigned long packets = 0; unsigned long packets = 0;
unsigned long drops = 0;
int i; int i;
pcpu_lstats = dev->ml_priv; pcpu_lstats = dev->ml_priv;
...@@ -102,11 +108,14 @@ static struct net_device_stats *loopback_get_stats(struct net_device *dev) ...@@ -102,11 +108,14 @@ static struct net_device_stats *loopback_get_stats(struct net_device *dev)
lb_stats = per_cpu_ptr(pcpu_lstats, i); lb_stats = per_cpu_ptr(pcpu_lstats, i);
bytes += lb_stats->bytes; bytes += lb_stats->bytes;
packets += lb_stats->packets; packets += lb_stats->packets;
drops += lb_stats->drops;
} }
stats->rx_packets = packets; stats->rx_packets = packets;
stats->tx_packets = packets; stats->tx_packets = packets;
stats->rx_bytes = bytes; stats->rx_dropped = drops;
stats->tx_bytes = bytes; stats->rx_errors = drops;
stats->rx_bytes = bytes;
stats->tx_bytes = bytes;
return stats; return stats;
} }
......
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