Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'net-convert-some-udp-tunnel-drivers-to-netdev_pcpu_stat_dstats'

Guillaume Nault says:

====================
net: Convert some UDP tunnel drivers to NETDEV_PCPU_STAT_DSTATS.

VXLAN, Geneve and Bareudp use various device counters for managing
RX and TX statistics:

* VXLAN uses the device core_stats for RX and TX drops, tstats for
regular RX/TX counters and DEV_STATS_INC() for various types of
RX/TX errors.

* Geneve uses tstats for regular RX/TX counters and DEV_STATS_INC()
for everything else, include RX/TX drops.

* Bareudp, was recently converted to follow VXLAN behaviour, that is,
device core_stats for RX and TX drops, tstats for regular RX/TX
counters and DEV_STATS_INC() for other counter types.

Let's consolidate statistics management around the dstats counters
instead. This avoids using core_stats in VXLAN and Bareudp, as
core_stats is supposed to be used by core networking code only (and not
in drivers). This also allows Geneve to avoid using atomic increments
when updating RX and TX drop counters, as dstats is per-cpu. Finally,
this also simplifies the code as all three modules now handle stats in
the same way and with only two different sets of counters (the per-cpu
dstats and the atomic DEV_STATS_INC()).

Patch 1 creates dstats helper functions that can be used outside of VRF
(until then, dstats was VRF-specific).
Then patches 2 to 4, convert VXLAN, Geneve and Bareudp, one by one.
====================

Link: https://patch.msgid.link/cover.1733313925.git.gnault@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+82 -63
+8 -8
drivers/net/bareudp.c
··· 84 84 85 85 if (skb_copy_bits(skb, BAREUDP_BASE_HLEN, &ipversion, 86 86 sizeof(ipversion))) { 87 - dev_core_stats_rx_dropped_inc(bareudp->dev); 87 + dev_dstats_rx_dropped(bareudp->dev); 88 88 goto drop; 89 89 } 90 90 ipversion >>= 4; ··· 94 94 } else if (ipversion == 6 && bareudp->multi_proto_mode) { 95 95 proto = htons(ETH_P_IPV6); 96 96 } else { 97 - dev_core_stats_rx_dropped_inc(bareudp->dev); 97 + dev_dstats_rx_dropped(bareudp->dev); 98 98 goto drop; 99 99 } 100 100 } else if (bareudp->ethertype == htons(ETH_P_MPLS_UC)) { ··· 108 108 ipv4_is_multicast(tunnel_hdr->daddr)) { 109 109 proto = htons(ETH_P_MPLS_MC); 110 110 } else { 111 - dev_core_stats_rx_dropped_inc(bareudp->dev); 111 + dev_dstats_rx_dropped(bareudp->dev); 112 112 goto drop; 113 113 } 114 114 } else { ··· 124 124 (addr_type & IPV6_ADDR_MULTICAST)) { 125 125 proto = htons(ETH_P_MPLS_MC); 126 126 } else { 127 - dev_core_stats_rx_dropped_inc(bareudp->dev); 127 + dev_dstats_rx_dropped(bareudp->dev); 128 128 goto drop; 129 129 } 130 130 } ··· 136 136 proto, 137 137 !net_eq(bareudp->net, 138 138 dev_net(bareudp->dev)))) { 139 - dev_core_stats_rx_dropped_inc(bareudp->dev); 139 + dev_dstats_rx_dropped(bareudp->dev); 140 140 goto drop; 141 141 } 142 142 ··· 144 144 145 145 tun_dst = udp_tun_rx_dst(skb, family, key, 0, 0); 146 146 if (!tun_dst) { 147 - dev_core_stats_rx_dropped_inc(bareudp->dev); 147 + dev_dstats_rx_dropped(bareudp->dev); 148 148 goto drop; 149 149 } 150 150 skb_dst_set(skb, &tun_dst->dst); ··· 194 194 len = skb->len; 195 195 err = gro_cells_receive(&bareudp->gro_cells, skb); 196 196 if (likely(err == NET_RX_SUCCESS)) 197 - dev_sw_netstats_rx_add(bareudp->dev, len); 197 + dev_dstats_rx_add(bareudp->dev, len); 198 198 199 199 return 0; 200 200 drop: ··· 589 589 dev->priv_flags |= IFF_NO_QUEUE; 590 590 dev->lltx = true; 591 591 dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST; 592 - dev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS; 592 + dev->pcpu_stat_type = NETDEV_PCPU_STAT_DSTATS; 593 593 } 594 594 595 595 static int bareudp_validate(struct nlattr *tb[], struct nlattr *data[],
+6 -6
drivers/net/geneve.c
··· 235 235 vni_to_tunnel_id(gnvh->vni), 236 236 gnvh->opt_len * 4); 237 237 if (!tun_dst) { 238 - DEV_STATS_INC(geneve->dev, rx_dropped); 238 + dev_dstats_rx_dropped(geneve->dev); 239 239 goto drop; 240 240 } 241 241 /* Update tunnel dst according to Geneve options. */ ··· 322 322 len = skb->len; 323 323 err = gro_cells_receive(&geneve->gro_cells, skb); 324 324 if (likely(err == NET_RX_SUCCESS)) 325 - dev_sw_netstats_rx_add(geneve->dev, len); 325 + dev_dstats_rx_add(geneve->dev, len); 326 326 327 327 return; 328 328 drop: ··· 387 387 388 388 if (unlikely((!geneve->cfg.inner_proto_inherit && 389 389 inner_proto != htons(ETH_P_TEB)))) { 390 - DEV_STATS_INC(geneve->dev, rx_dropped); 390 + dev_dstats_rx_dropped(geneve->dev); 391 391 goto drop; 392 392 } 393 393 394 394 opts_len = geneveh->opt_len * 4; 395 395 if (iptunnel_pull_header(skb, GENEVE_BASE_HLEN + opts_len, inner_proto, 396 396 !net_eq(geneve->net, dev_net(geneve->dev)))) { 397 - DEV_STATS_INC(geneve->dev, rx_dropped); 397 + dev_dstats_rx_dropped(geneve->dev); 398 398 goto drop; 399 399 } 400 400 ··· 1023 1023 if (unlikely(!info || !(info->mode & IP_TUNNEL_INFO_TX))) { 1024 1024 netdev_dbg(dev, "no tunnel metadata\n"); 1025 1025 dev_kfree_skb(skb); 1026 - DEV_STATS_INC(dev, tx_dropped); 1026 + dev_dstats_tx_dropped(dev); 1027 1027 return NETDEV_TX_OK; 1028 1028 } 1029 1029 } else { ··· 1202 1202 dev->hw_features |= NETIF_F_RXCSUM; 1203 1203 dev->hw_features |= NETIF_F_GSO_SOFTWARE; 1204 1204 1205 - dev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS; 1205 + dev->pcpu_stat_type = NETDEV_PCPU_STAT_DSTATS; 1206 1206 /* MTU range: 68 - (something less than 65535) */ 1207 1207 dev->min_mtu = ETH_MIN_MTU; 1208 1208 /* The max_mtu calculation does not take account of GENEVE
+14 -35
drivers/net/vrf.c
··· 122 122 int ifindex; 123 123 }; 124 124 125 - static void vrf_rx_stats(struct net_device *dev, int len) 126 - { 127 - struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats); 128 - 129 - u64_stats_update_begin(&dstats->syncp); 130 - u64_stats_inc(&dstats->rx_packets); 131 - u64_stats_add(&dstats->rx_bytes, len); 132 - u64_stats_update_end(&dstats->syncp); 133 - } 134 - 135 125 static void vrf_tx_error(struct net_device *vrf_dev, struct sk_buff *skb) 136 126 { 137 127 vrf_dev->stats.tx_errors++; ··· 359 369 static int vrf_local_xmit(struct sk_buff *skb, struct net_device *dev, 360 370 struct dst_entry *dst) 361 371 { 362 - int len = skb->len; 372 + unsigned int len = skb->len; 363 373 364 374 skb_orphan(skb); 365 375 ··· 372 382 373 383 skb->protocol = eth_type_trans(skb, dev); 374 384 375 - if (likely(__netif_rx(skb) == NET_RX_SUCCESS)) { 376 - vrf_rx_stats(dev, len); 377 - } else { 378 - struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats); 379 - 380 - u64_stats_update_begin(&dstats->syncp); 381 - u64_stats_inc(&dstats->rx_drops); 382 - u64_stats_update_end(&dstats->syncp); 383 - } 385 + if (likely(__netif_rx(skb) == NET_RX_SUCCESS)) 386 + dev_dstats_rx_add(dev, len); 387 + else 388 + dev_dstats_rx_dropped(dev); 384 389 385 390 return NETDEV_TX_OK; 386 391 } ··· 563 578 564 579 static netdev_tx_t vrf_xmit(struct sk_buff *skb, struct net_device *dev) 565 580 { 566 - struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats); 581 + unsigned int len = skb->len; 582 + netdev_tx_t ret; 567 583 568 - int len = skb->len; 569 - netdev_tx_t ret = is_ip_tx_frame(skb, dev); 570 - 571 - u64_stats_update_begin(&dstats->syncp); 572 - if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { 573 - 574 - u64_stats_inc(&dstats->tx_packets); 575 - u64_stats_add(&dstats->tx_bytes, len); 576 - } else { 577 - u64_stats_inc(&dstats->tx_drops); 578 - } 579 - u64_stats_update_end(&dstats->syncp); 584 + ret = is_ip_tx_frame(skb, dev); 585 + if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) 586 + dev_dstats_tx_add(dev, len); 587 + else 588 + dev_dstats_tx_dropped(dev); 580 589 581 590 return ret; 582 591 } ··· 1343 1364 if (!is_ndisc) { 1344 1365 struct net_device *orig_dev = skb->dev; 1345 1366 1346 - vrf_rx_stats(vrf_dev, skb->len); 1367 + dev_dstats_rx_add(vrf_dev, skb->len); 1347 1368 skb->dev = vrf_dev; 1348 1369 skb->skb_iif = vrf_dev->ifindex; 1349 1370 ··· 1399 1420 goto out; 1400 1421 } 1401 1422 1402 - vrf_rx_stats(vrf_dev, skb->len); 1423 + dev_dstats_rx_add(vrf_dev, skb->len); 1403 1424 1404 1425 if (!list_empty(&vrf_dev->ptype_all)) { 1405 1426 int err;
+14 -14
drivers/net/vxlan/vxlan_core.c
··· 1818 1818 1819 1819 if (unlikely(!(vxlan->dev->flags & IFF_UP))) { 1820 1820 rcu_read_unlock(); 1821 - dev_core_stats_rx_dropped_inc(vxlan->dev); 1821 + dev_dstats_rx_dropped(vxlan->dev); 1822 1822 vxlan_vnifilter_count(vxlan, vni, vninode, 1823 1823 VXLAN_VNI_STATS_RX_DROPS, 0); 1824 1824 reason = SKB_DROP_REASON_DEV_READY; 1825 1825 goto drop; 1826 1826 } 1827 1827 1828 - dev_sw_netstats_rx_add(vxlan->dev, skb->len); 1828 + dev_dstats_rx_add(vxlan->dev, skb->len); 1829 1829 vxlan_vnifilter_count(vxlan, vni, vninode, VXLAN_VNI_STATS_RX, skb->len); 1830 1830 gro_cells_receive(&vxlan->gro_cells, skb); 1831 1831 ··· 1880 1880 goto out; 1881 1881 1882 1882 if (!pskb_may_pull(skb, arp_hdr_len(dev))) { 1883 - dev_core_stats_tx_dropped_inc(dev); 1883 + dev_dstats_tx_dropped(dev); 1884 1884 vxlan_vnifilter_count(vxlan, vni, NULL, 1885 1885 VXLAN_VNI_STATS_TX_DROPS, 0); 1886 1886 goto out; ··· 1938 1938 reply->pkt_type = PACKET_HOST; 1939 1939 1940 1940 if (netif_rx(reply) == NET_RX_DROP) { 1941 - dev_core_stats_rx_dropped_inc(dev); 1941 + dev_dstats_rx_dropped(dev); 1942 1942 vxlan_vnifilter_count(vxlan, vni, NULL, 1943 1943 VXLAN_VNI_STATS_RX_DROPS, 0); 1944 1944 } ··· 2097 2097 goto out; 2098 2098 2099 2099 if (netif_rx(reply) == NET_RX_DROP) { 2100 - dev_core_stats_rx_dropped_inc(dev); 2100 + dev_dstats_rx_dropped(dev); 2101 2101 vxlan_vnifilter_count(vxlan, vni, NULL, 2102 2102 VXLAN_VNI_STATS_RX_DROPS, 0); 2103 2103 } ··· 2271 2271 { 2272 2272 union vxlan_addr loopback; 2273 2273 union vxlan_addr *remote_ip = &dst_vxlan->default_dst.remote_ip; 2274 + unsigned int len = skb->len; 2274 2275 struct net_device *dev; 2275 - int len = skb->len; 2276 2276 2277 2277 skb->pkt_type = PACKET_HOST; 2278 2278 skb->encapsulation = 0; ··· 2299 2299 if ((dst_vxlan->cfg.flags & VXLAN_F_LEARN) && snoop) 2300 2300 vxlan_snoop(dev, &loopback, eth_hdr(skb)->h_source, 0, vni); 2301 2301 2302 - dev_sw_netstats_tx_add(src_vxlan->dev, 1, len); 2302 + dev_dstats_tx_add(src_vxlan->dev, len); 2303 2303 vxlan_vnifilter_count(src_vxlan, vni, NULL, VXLAN_VNI_STATS_TX, len); 2304 2304 2305 2305 if (__netif_rx(skb) == NET_RX_SUCCESS) { 2306 - dev_sw_netstats_rx_add(dst_vxlan->dev, len); 2306 + dev_dstats_rx_add(dst_vxlan->dev, len); 2307 2307 vxlan_vnifilter_count(dst_vxlan, vni, NULL, VXLAN_VNI_STATS_RX, 2308 2308 len); 2309 2309 } else { 2310 2310 drop: 2311 - dev_core_stats_rx_dropped_inc(dev); 2311 + dev_dstats_rx_dropped(dev); 2312 2312 vxlan_vnifilter_count(dst_vxlan, vni, NULL, 2313 2313 VXLAN_VNI_STATS_RX_DROPS, 0); 2314 2314 } ··· 2621 2621 return; 2622 2622 2623 2623 drop: 2624 - dev_core_stats_tx_dropped_inc(dev); 2624 + dev_dstats_tx_dropped(dev); 2625 2625 vxlan_vnifilter_count(vxlan, vni, NULL, VXLAN_VNI_STATS_TX_DROPS, 0); 2626 2626 kfree_skb_reason(skb, reason); 2627 2627 return; ··· 2666 2666 return; 2667 2667 2668 2668 drop: 2669 - dev_core_stats_tx_dropped_inc(dev); 2669 + dev_dstats_tx_dropped(dev); 2670 2670 vxlan_vnifilter_count(netdev_priv(dev), vni, NULL, 2671 2671 VXLAN_VNI_STATS_TX_DROPS, 0); 2672 2672 dev_kfree_skb(skb); ··· 2704 2704 return NETDEV_TX_OK; 2705 2705 2706 2706 drop: 2707 - dev_core_stats_tx_dropped_inc(dev); 2707 + dev_dstats_tx_dropped(dev); 2708 2708 vxlan_vnifilter_count(netdev_priv(dev), vni, NULL, 2709 2709 VXLAN_VNI_STATS_TX_DROPS, 0); 2710 2710 dev_kfree_skb(skb); ··· 2801 2801 !is_multicast_ether_addr(eth->h_dest)) 2802 2802 vxlan_fdb_miss(vxlan, eth->h_dest); 2803 2803 2804 - dev_core_stats_tx_dropped_inc(dev); 2804 + dev_dstats_tx_dropped(dev); 2805 2805 vxlan_vnifilter_count(vxlan, vni, NULL, 2806 2806 VXLAN_VNI_STATS_TX_DROPS, 0); 2807 2807 kfree_skb_reason(skb, SKB_DROP_REASON_VXLAN_NO_REMOTE); ··· 3371 3371 dev->min_mtu = ETH_MIN_MTU; 3372 3372 dev->max_mtu = ETH_MAX_MTU; 3373 3373 3374 - dev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS; 3374 + dev->pcpu_stat_type = NETDEV_PCPU_STAT_DSTATS; 3375 3375 INIT_LIST_HEAD(&vxlan->next); 3376 3376 3377 3377 timer_setup(&vxlan->age_timer, vxlan_cleanup, TIMER_DEFERRABLE);
+40
include/linux/netdevice.h
··· 2854 2854 u64_stats_update_end(&lstats->syncp); 2855 2855 } 2856 2856 2857 + static inline void dev_dstats_rx_add(struct net_device *dev, 2858 + unsigned int len) 2859 + { 2860 + struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats); 2861 + 2862 + u64_stats_update_begin(&dstats->syncp); 2863 + u64_stats_inc(&dstats->rx_packets); 2864 + u64_stats_add(&dstats->rx_bytes, len); 2865 + u64_stats_update_end(&dstats->syncp); 2866 + } 2867 + 2868 + static inline void dev_dstats_rx_dropped(struct net_device *dev) 2869 + { 2870 + struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats); 2871 + 2872 + u64_stats_update_begin(&dstats->syncp); 2873 + u64_stats_inc(&dstats->rx_drops); 2874 + u64_stats_update_end(&dstats->syncp); 2875 + } 2876 + 2877 + static inline void dev_dstats_tx_add(struct net_device *dev, 2878 + unsigned int len) 2879 + { 2880 + struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats); 2881 + 2882 + u64_stats_update_begin(&dstats->syncp); 2883 + u64_stats_inc(&dstats->tx_packets); 2884 + u64_stats_add(&dstats->tx_bytes, len); 2885 + u64_stats_update_end(&dstats->syncp); 2886 + } 2887 + 2888 + static inline void dev_dstats_tx_dropped(struct net_device *dev) 2889 + { 2890 + struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats); 2891 + 2892 + u64_stats_update_begin(&dstats->syncp); 2893 + u64_stats_inc(&dstats->tx_drops); 2894 + u64_stats_update_end(&dstats->syncp); 2895 + } 2896 + 2857 2897 #define __netdev_alloc_pcpu_stats(type, gfp) \ 2858 2898 ({ \ 2859 2899 typeof(type) __percpu *pcpu_stats = alloc_percpu_gfp(type, gfp);\