Commit caf586e5f23cebb2a68cbaf288d59dbbf2d74052

Authored by Eric Dumazet
Committed by David S. Miller
1 parent a00eac0c45

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).
... ... @@ -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 }
... ... @@ -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);
... ... @@ -679,8 +679,7 @@
679 679 skb_reset_network_header(skb);
680 680 ipgre_ecn_decapsulate(iph, skb);
681 681  
682   - if (netif_rx(skb) == NET_RX_DROP)
683   - tunnel->dev->stats.rx_dropped++;
  682 + netif_rx(skb);
684 683  
685 684 rcu_read_unlock();
686 685 return 0;
... ... @@ -414,8 +414,7 @@
414 414  
415 415 ipip_ecn_decapsulate(iph, skb);
416 416  
417   - if (netif_rx(skb) == NET_RX_DROP)
418   - tunnel->dev->stats.rx_dropped++;
  417 + netif_rx(skb);
419 418  
420 419 rcu_read_unlock();
421 420 return 0;
net/ipv6/ip6_tunnel.c
... ... @@ -768,8 +768,7 @@
768 768  
769 769 dscp_ecn_decapsulate(t, ipv6h, skb);
770 770  
771   - if (netif_rx(skb) == NET_RX_DROP)
772   - t->dev->stats.rx_dropped++;
  771 + netif_rx(skb);
773 772  
774 773 rcu_read_unlock();
775 774 return 0;
... ... @@ -666,8 +666,7 @@
666 666  
667 667 skb_tunnel_rx(skb, reg_dev);
668 668  
669   - if (netif_rx(skb) == NET_RX_DROP)
670   - reg_dev->stats.rx_dropped++;
  669 + netif_rx(skb);
671 670  
672 671 dev_put(reg_dev);
673 672 return 0;
... ... @@ -600,8 +600,7 @@
600 600  
601 601 ipip6_ecn_decapsulate(iph, skb);
602 602  
603   - if (netif_rx(skb) == NET_RX_DROP)
604   - tunnel->dev->stats.rx_dropped++;
  603 + netif_rx(skb);
605 604  
606 605 rcu_read_unlock();
607 606 return 0;