Commit caf586e5f23cebb2a68cbaf288d59dbbf2d74052
Committed by
David S. Miller
1 parent
a00eac0c45
Exists in
master
and in
39 other branches
net: add a core netdev->rx_dropped counter
In various situations, a device provides a packet to our stack and we drop it before it enters protocol stack : - softnet backlog full (accounted in /proc/net/softnet_stat) - bad vlan tag (not accounted) - unknown/unregistered protocol (not accounted) We can handle a per-device counter of such dropped frames at core level, and automatically adds it to the device provided stats (rx_dropped), so that standard tools can be used (ifconfig, ip link, cat /proc/net/dev) This is a generalization of commit 8990f468a (net: rx_dropped accounting), thus reverting it. Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 11 changed files with 26 additions and 34 deletions Side-by-side Diff
drivers/net/loopback.c
... | ... | @@ -64,7 +64,6 @@ |
64 | 64 | u64 packets; |
65 | 65 | u64 bytes; |
66 | 66 | struct u64_stats_sync syncp; |
67 | - unsigned long drops; | |
68 | 67 | }; |
69 | 68 | |
70 | 69 | /* |
... | ... | @@ -90,8 +89,7 @@ |
90 | 89 | lb_stats->bytes += len; |
91 | 90 | lb_stats->packets++; |
92 | 91 | u64_stats_update_end(&lb_stats->syncp); |
93 | - } else | |
94 | - lb_stats->drops++; | |
92 | + } | |
95 | 93 | |
96 | 94 | return NETDEV_TX_OK; |
97 | 95 | } |
... | ... | @@ -101,7 +99,6 @@ |
101 | 99 | { |
102 | 100 | u64 bytes = 0; |
103 | 101 | u64 packets = 0; |
104 | - u64 drops = 0; | |
105 | 102 | int i; |
106 | 103 | |
107 | 104 | for_each_possible_cpu(i) { |
108 | 105 | |
... | ... | @@ -115,14 +112,11 @@ |
115 | 112 | tbytes = lb_stats->bytes; |
116 | 113 | tpackets = lb_stats->packets; |
117 | 114 | } while (u64_stats_fetch_retry(&lb_stats->syncp, start)); |
118 | - drops += lb_stats->drops; | |
119 | 115 | bytes += tbytes; |
120 | 116 | packets += tpackets; |
121 | 117 | } |
122 | 118 | stats->rx_packets = packets; |
123 | 119 | stats->tx_packets = packets; |
124 | - stats->rx_dropped = drops; | |
125 | - stats->rx_errors = drops; | |
126 | 120 | stats->rx_bytes = bytes; |
127 | 121 | stats->tx_bytes = bytes; |
128 | 122 | return stats; |
include/linux/netdevice.h
... | ... | @@ -884,6 +884,9 @@ |
884 | 884 | int iflink; |
885 | 885 | |
886 | 886 | struct net_device_stats stats; |
887 | + atomic_long_t rx_dropped; /* dropped packets by core network | |
888 | + * Do not use this in drivers. | |
889 | + */ | |
887 | 890 | |
888 | 891 | #ifdef CONFIG_WIRELESS_EXT |
889 | 892 | /* List of functions to handle Wireless Extensions (instead of ioctl). |
net/8021q/vlan.h
... | ... | @@ -25,7 +25,6 @@ |
25 | 25 | * @rx_multicast: number of received multicast packets |
26 | 26 | * @syncp: synchronization point for 64bit counters |
27 | 27 | * @rx_errors: number of errors |
28 | - * @rx_dropped: number of dropped packets | |
29 | 28 | */ |
30 | 29 | struct vlan_rx_stats { |
31 | 30 | u64 rx_packets; |
... | ... | @@ -33,7 +32,6 @@ |
33 | 32 | u64 rx_multicast; |
34 | 33 | struct u64_stats_sync syncp; |
35 | 34 | unsigned long rx_errors; |
36 | - unsigned long rx_dropped; | |
37 | 35 | }; |
38 | 36 | |
39 | 37 | /** |
net/8021q/vlan_core.c
... | ... | @@ -33,6 +33,7 @@ |
33 | 33 | return polling ? netif_receive_skb(skb) : netif_rx(skb); |
34 | 34 | |
35 | 35 | drop: |
36 | + atomic_long_inc(&skb->dev->rx_dropped); | |
36 | 37 | dev_kfree_skb_any(skb); |
37 | 38 | return NET_RX_DROP; |
38 | 39 | } |
... | ... | @@ -123,6 +124,7 @@ |
123 | 124 | return dev_gro_receive(napi, skb); |
124 | 125 | |
125 | 126 | drop: |
127 | + atomic_long_inc(&skb->dev->rx_dropped); | |
126 | 128 | return GRO_DROP; |
127 | 129 | } |
128 | 130 |
net/8021q/vlan_dev.c
... | ... | @@ -225,16 +225,15 @@ |
225 | 225 | } |
226 | 226 | } |
227 | 227 | |
228 | - if (unlikely(netif_rx(skb) == NET_RX_DROP)) { | |
229 | - if (rx_stats) | |
230 | - rx_stats->rx_dropped++; | |
231 | - } | |
228 | + netif_rx(skb); | |
229 | + | |
232 | 230 | rcu_read_unlock(); |
233 | 231 | return NET_RX_SUCCESS; |
234 | 232 | |
235 | 233 | err_unlock: |
236 | 234 | rcu_read_unlock(); |
237 | 235 | err_free: |
236 | + atomic_long_inc(&dev->rx_dropped); | |
238 | 237 | kfree_skb(skb); |
239 | 238 | return NET_RX_DROP; |
240 | 239 | } |
241 | 240 | |
242 | 241 | |
... | ... | @@ -846,15 +845,13 @@ |
846 | 845 | accum.rx_packets += rxpackets; |
847 | 846 | accum.rx_bytes += rxbytes; |
848 | 847 | accum.rx_multicast += rxmulticast; |
849 | - /* rx_errors, rx_dropped are ulong, not protected by syncp */ | |
848 | + /* rx_errors is ulong, not protected by syncp */ | |
850 | 849 | accum.rx_errors += p->rx_errors; |
851 | - accum.rx_dropped += p->rx_dropped; | |
852 | 850 | } |
853 | 851 | stats->rx_packets = accum.rx_packets; |
854 | 852 | stats->rx_bytes = accum.rx_bytes; |
855 | 853 | stats->rx_errors = accum.rx_errors; |
856 | 854 | stats->multicast = accum.rx_multicast; |
857 | - stats->rx_dropped = accum.rx_dropped; | |
858 | 855 | } |
859 | 856 | return stats; |
860 | 857 | } |
net/core/dev.c
... | ... | @@ -1483,8 +1483,9 @@ |
1483 | 1483 | skb_orphan(skb); |
1484 | 1484 | nf_reset(skb); |
1485 | 1485 | |
1486 | - if (!(dev->flags & IFF_UP) || | |
1487 | - (skb->len > (dev->mtu + dev->hard_header_len))) { | |
1486 | + if (unlikely(!(dev->flags & IFF_UP) || | |
1487 | + (skb->len > (dev->mtu + dev->hard_header_len)))) { | |
1488 | + atomic_long_inc(&dev->rx_dropped); | |
1488 | 1489 | kfree_skb(skb); |
1489 | 1490 | return NET_RX_DROP; |
1490 | 1491 | } |
... | ... | @@ -2548,6 +2549,7 @@ |
2548 | 2549 | |
2549 | 2550 | local_irq_restore(flags); |
2550 | 2551 | |
2552 | + atomic_long_inc(&skb->dev->rx_dropped); | |
2551 | 2553 | kfree_skb(skb); |
2552 | 2554 | return NET_RX_DROP; |
2553 | 2555 | } |
... | ... | @@ -2995,6 +2997,7 @@ |
2995 | 2997 | if (pt_prev) { |
2996 | 2998 | ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev); |
2997 | 2999 | } else { |
3000 | + atomic_long_inc(&skb->dev->rx_dropped); | |
2998 | 3001 | kfree_skb(skb); |
2999 | 3002 | /* Jamal, now you will not able to escape explaining |
3000 | 3003 | * me how you were going to use this. :-) |
3001 | 3004 | |
3002 | 3005 | |
... | ... | @@ -5429,14 +5432,14 @@ |
5429 | 5432 | |
5430 | 5433 | if (ops->ndo_get_stats64) { |
5431 | 5434 | memset(storage, 0, sizeof(*storage)); |
5432 | - return ops->ndo_get_stats64(dev, storage); | |
5433 | - } | |
5434 | - if (ops->ndo_get_stats) { | |
5435 | + ops->ndo_get_stats64(dev, storage); | |
5436 | + } else if (ops->ndo_get_stats) { | |
5435 | 5437 | netdev_stats_to_stats64(storage, ops->ndo_get_stats(dev)); |
5436 | - return storage; | |
5438 | + } else { | |
5439 | + netdev_stats_to_stats64(storage, &dev->stats); | |
5440 | + dev_txq_stats_fold(dev, storage); | |
5437 | 5441 | } |
5438 | - netdev_stats_to_stats64(storage, &dev->stats); | |
5439 | - dev_txq_stats_fold(dev, storage); | |
5442 | + storage->rx_dropped += atomic_long_read(&dev->rx_dropped); | |
5440 | 5443 | return storage; |
5441 | 5444 | } |
5442 | 5445 | EXPORT_SYMBOL(dev_get_stats); |
net/ipv4/ip_gre.c
net/ipv4/ipip.c
net/ipv6/ip6_tunnel.c
net/ipv6/ip6mr.c