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 'netdevsim-implement-rx-statistics-using-netdev_pcpu_stat_dstats'

Breno Leitao says:

====================
netdevsim: implement RX statistics using NETDEV_PCPU_STAT_DSTATS

The netdevsim driver previously lacked RX statistics support, which
prevented its use with the GenerateTraffic() test framework, as this
framework verifies traffic flow by checking RX byte counts.

This patch migrates netdevsim from its custom statistics collection to
the NETDEV_PCPU_STAT_DSTATS framework, as suggested by Jakub. This
change not only standardizes the statistics handling but also adds the
necessary RX statistics support required by the test framework.

v3: https://lore.kernel.org/20250617-netdevsim_stat-v3-0-afe4bdcbf237@debian.org
v2: https://lore.kernel.org/20250613-netdevsim_stat-v2-0-98fa38836c48@debian.org
v1: https://lore.kernel.org/20250611-netdevsim_stat-v1-0-c11b657d96bf@debian.org
====================

Link: https://patch.msgid.link/20250618-netdevsim_stat-v4-0-19fe0d35e28e@debian.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+33 -38
+23 -33
drivers/net/netdevsim/netdev.c
··· 93 93 hrtimer_start(&rq->napi_timer, us_to_ktime(5), HRTIMER_MODE_REL); 94 94 95 95 rcu_read_unlock(); 96 - u64_stats_update_begin(&ns->syncp); 97 - ns->tx_packets++; 98 - ns->tx_bytes += len; 99 - u64_stats_update_end(&ns->syncp); 96 + dev_dstats_tx_add(dev, skb->len); 100 97 return NETDEV_TX_OK; 101 98 102 99 out_drop_free: 103 100 dev_kfree_skb(skb); 104 101 out_drop_cnt: 105 102 rcu_read_unlock(); 106 - u64_stats_update_begin(&ns->syncp); 107 - ns->tx_dropped++; 108 - u64_stats_update_end(&ns->syncp); 103 + dev_dstats_tx_dropped(dev); 109 104 return NETDEV_TX_OK; 110 105 } 111 106 ··· 119 124 WRITE_ONCE(dev->mtu, new_mtu); 120 125 121 126 return 0; 122 - } 123 - 124 - static void 125 - nsim_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) 126 - { 127 - struct netdevsim *ns = netdev_priv(dev); 128 - unsigned int start; 129 - 130 - do { 131 - start = u64_stats_fetch_begin(&ns->syncp); 132 - stats->tx_bytes = ns->tx_bytes; 133 - stats->tx_packets = ns->tx_packets; 134 - stats->tx_dropped = ns->tx_dropped; 135 - } while (u64_stats_fetch_retry(&ns->syncp, start)); 136 127 } 137 128 138 129 static int ··· 331 350 332 351 static int nsim_rcv(struct nsim_rq *rq, int budget) 333 352 { 353 + struct net_device *dev = rq->napi.dev; 334 354 struct sk_buff *skb; 335 - int i; 355 + unsigned int skblen; 356 + int i, ret; 336 357 337 358 for (i = 0; i < budget; i++) { 338 359 if (skb_queue_empty(&rq->skb_queue)) 339 360 break; 340 361 341 362 skb = skb_dequeue(&rq->skb_queue); 363 + /* skb might be discard at netif_receive_skb, save the len */ 364 + skblen = skb->len; 342 365 skb_mark_napi_id(skb, &rq->napi); 343 - netif_receive_skb(skb); 366 + ret = netif_receive_skb(skb); 367 + if (ret == NET_RX_SUCCESS) 368 + dev_dstats_rx_add(dev, skblen); 369 + else 370 + dev_dstats_rx_dropped(dev); 344 371 } 345 372 346 373 return i; ··· 545 556 .ndo_set_mac_address = eth_mac_addr, 546 557 .ndo_validate_addr = eth_validate_addr, 547 558 .ndo_change_mtu = nsim_change_mtu, 548 - .ndo_get_stats64 = nsim_get_stats64, 549 559 .ndo_set_vf_mac = nsim_set_vf_mac, 550 560 .ndo_set_vf_vlan = nsim_set_vf_vlan, 551 561 .ndo_set_vf_rate = nsim_set_vf_rate, ··· 568 580 .ndo_set_mac_address = eth_mac_addr, 569 581 .ndo_validate_addr = eth_validate_addr, 570 582 .ndo_change_mtu = nsim_change_mtu, 571 - .ndo_get_stats64 = nsim_get_stats64, 572 583 .ndo_setup_tc = nsim_setup_tc, 573 584 .ndo_set_features = nsim_set_features, 574 585 }; ··· 581 594 struct rtnl_link_stats64 rtstats = {}; 582 595 583 596 if (!idx) 584 - nsim_get_stats64(dev, &rtstats); 597 + dev_get_stats(dev, &rtstats); 585 598 586 599 stats->packets = rtstats.rx_packets - !!rtstats.rx_packets; 587 600 stats->bytes = rtstats.rx_bytes; ··· 593 606 struct rtnl_link_stats64 rtstats = {}; 594 607 595 608 if (!idx) 596 - nsim_get_stats64(dev, &rtstats); 609 + dev_get_stats(dev, &rtstats); 597 610 598 611 stats->packets = rtstats.tx_packets - !!rtstats.tx_packets; 599 612 stats->bytes = rtstats.tx_bytes; ··· 605 618 { 606 619 struct rtnl_link_stats64 rtstats = {}; 607 620 608 - nsim_get_stats64(dev, &rtstats); 621 + dev_get_stats(dev, &rtstats); 609 622 610 623 rx->packets = !!rtstats.rx_packets; 611 624 rx->bytes = 0; ··· 632 645 return rq; 633 646 } 634 647 635 - static void nsim_queue_free(struct nsim_rq *rq) 648 + static void nsim_queue_free(struct net_device *dev, struct nsim_rq *rq) 636 649 { 637 650 hrtimer_cancel(&rq->napi_timer); 651 + local_bh_disable(); 652 + dev_dstats_rx_dropped_add(dev, rq->skb_queue.qlen); 653 + local_bh_enable(); 638 654 skb_queue_purge_reason(&rq->skb_queue, SKB_DROP_REASON_QUEUE_PURGE); 639 655 kfree(rq); 640 656 } ··· 684 694 return 0; 685 695 686 696 err_free: 687 - nsim_queue_free(qmem->rq); 697 + nsim_queue_free(dev, qmem->rq); 688 698 return err; 689 699 } 690 700 ··· 698 708 if (!ns->rq_reset_mode) 699 709 netif_napi_del_locked(&qmem->rq->napi); 700 710 page_pool_destroy(qmem->rq->page_pool); 701 - nsim_queue_free(qmem->rq); 711 + nsim_queue_free(dev, qmem->rq); 702 712 } 703 713 } 704 714 ··· 880 890 NETIF_F_HW_CSUM | 881 891 NETIF_F_LRO | 882 892 NETIF_F_TSO; 893 + dev->pcpu_stat_type = NETDEV_PCPU_STAT_DSTATS; 883 894 dev->max_mtu = ETH_MAX_MTU; 884 895 dev->xdp_features = NETDEV_XDP_ACT_HW_OFFLOAD; 885 896 } ··· 916 925 int i; 917 926 918 927 for (i = 0; i < dev->num_rx_queues; i++) 919 - nsim_queue_free(ns->rq[i]); 928 + nsim_queue_free(dev, ns->rq[i]); 920 929 921 930 kfree(ns->rq); 922 931 ns->rq = NULL; ··· 1013 1022 dev_net_set(dev, nsim_dev_net(nsim_dev)); 1014 1023 ns = netdev_priv(dev); 1015 1024 ns->netdev = dev; 1016 - u64_stats_init(&ns->syncp); 1017 1025 ns->nsim_dev = nsim_dev; 1018 1026 ns->nsim_dev_port = nsim_dev_port; 1019 1027 ns->nsim_bus_dev = nsim_dev->nsim_bus_dev;
-5
drivers/net/netdevsim/netdevsim.h
··· 108 108 109 109 int rq_reset_mode; 110 110 111 - u64 tx_packets; 112 - u64 tx_bytes; 113 - u64 tx_dropped; 114 - struct u64_stats_sync syncp; 115 - 116 111 struct nsim_bus_dev *nsim_bus_dev; 117 112 118 113 struct bpf_prog *bpf_offloaded;
+10
include/linux/netdevice.h
··· 3016 3016 u64_stats_update_end(&dstats->syncp); 3017 3017 } 3018 3018 3019 + static inline void dev_dstats_rx_dropped_add(struct net_device *dev, 3020 + unsigned int packets) 3021 + { 3022 + struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats); 3023 + 3024 + u64_stats_update_begin(&dstats->syncp); 3025 + u64_stats_add(&dstats->rx_drops, packets); 3026 + u64_stats_update_end(&dstats->syncp); 3027 + } 3028 + 3019 3029 static inline void dev_dstats_tx_add(struct net_device *dev, 3020 3030 unsigned int len) 3021 3031 {