diff options
author | Eric Dumazet <dada1@cosmosbay.com> | 2009-04-17 18:03:10 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-04-20 05:25:26 -0400 |
commit | 7eebb0b28f755e297d355a205bb04945b256db6b (patch) | |
tree | ae09d5928a764f5cb58eb217ec0d910e5d332474 /drivers/net | |
parent | eb62efd287fe6e12d18083287e38e4a811c28256 (diff) |
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: Eric Dumazet <dada1@cosmosbay.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/loopback.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index b7d438a367f3..6f71157bea8e 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c | |||
@@ -62,6 +62,7 @@ | |||
62 | struct pcpu_lstats { | 62 | struct pcpu_lstats { |
63 | unsigned long packets; | 63 | unsigned long packets; |
64 | unsigned long bytes; | 64 | unsigned long bytes; |
65 | unsigned long drops; | ||
65 | }; | 66 | }; |
66 | 67 | ||
67 | /* | 68 | /* |
@@ -71,18 +72,22 @@ struct pcpu_lstats { | |||
71 | static int loopback_xmit(struct sk_buff *skb, struct net_device *dev) | 72 | static int loopback_xmit(struct sk_buff *skb, struct net_device *dev) |
72 | { | 73 | { |
73 | struct pcpu_lstats *pcpu_lstats, *lb_stats; | 74 | struct pcpu_lstats *pcpu_lstats, *lb_stats; |
75 | int len; | ||
74 | 76 | ||
75 | skb_orphan(skb); | 77 | skb_orphan(skb); |
76 | 78 | ||
77 | skb->protocol = eth_type_trans(skb,dev); | 79 | skb->protocol = eth_type_trans(skb, dev); |
78 | 80 | ||
79 | /* it's OK to use per_cpu_ptr() because BHs are off */ | 81 | /* it's OK to use per_cpu_ptr() because BHs are off */ |
80 | pcpu_lstats = dev->ml_priv; | 82 | pcpu_lstats = dev->ml_priv; |
81 | lb_stats = per_cpu_ptr(pcpu_lstats, smp_processor_id()); | 83 | lb_stats = per_cpu_ptr(pcpu_lstats, smp_processor_id()); |
82 | lb_stats->bytes += skb->len; | ||
83 | lb_stats->packets++; | ||
84 | 84 | ||
85 | netif_rx(skb); | 85 | len = skb->len; |
86 | if (likely(netif_rx(skb) == NET_RX_SUCCESS)) { | ||
87 | lb_stats->bytes += len; | ||
88 | lb_stats->packets++; | ||
89 | } else | ||
90 | lb_stats->drops++; | ||
86 | 91 | ||
87 | return 0; | 92 | return 0; |
88 | } | 93 | } |
@@ -93,6 +98,7 @@ static struct net_device_stats *loopback_get_stats(struct net_device *dev) | |||
93 | struct net_device_stats *stats = &dev->stats; | 98 | struct net_device_stats *stats = &dev->stats; |
94 | unsigned long bytes = 0; | 99 | unsigned long bytes = 0; |
95 | unsigned long packets = 0; | 100 | unsigned long packets = 0; |
101 | unsigned long drops = 0; | ||
96 | int i; | 102 | int i; |
97 | 103 | ||
98 | pcpu_lstats = dev->ml_priv; | 104 | pcpu_lstats = dev->ml_priv; |
@@ -102,11 +108,14 @@ static struct net_device_stats *loopback_get_stats(struct net_device *dev) | |||
102 | lb_stats = per_cpu_ptr(pcpu_lstats, i); | 108 | lb_stats = per_cpu_ptr(pcpu_lstats, i); |
103 | bytes += lb_stats->bytes; | 109 | bytes += lb_stats->bytes; |
104 | packets += lb_stats->packets; | 110 | packets += lb_stats->packets; |
111 | drops += lb_stats->drops; | ||
105 | } | 112 | } |
106 | stats->rx_packets = packets; | 113 | stats->rx_packets = packets; |
107 | stats->tx_packets = packets; | 114 | stats->tx_packets = packets; |
108 | stats->rx_bytes = bytes; | 115 | stats->rx_dropped = drops; |
109 | stats->tx_bytes = bytes; | 116 | stats->rx_errors = drops; |
117 | stats->rx_bytes = bytes; | ||
118 | stats->tx_bytes = bytes; | ||
110 | return stats; | 119 | return stats; |
111 | } | 120 | } |
112 | 121 | ||