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

netdevsim: report stats by default, like a real device

Real devices should implement qstats. Devices which support
pause or FEC configuration should also report the relevant stats.

nsim was missing FEC stats completely, some of the qstats
and pause stats required toggling a debugfs knob.

Note that the tests which used pause always initialize the setting
so they shouldn't be affected by the different starting value.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Jakub Kicinski and committed by
David S. Miller
f216306b 796c8c7f

+60
+11
drivers/net/netdevsim/ethtool.c
··· 140 140 return 0; 141 141 } 142 142 143 + static void 144 + nsim_get_fec_stats(struct net_device *dev, struct ethtool_fec_stats *fec_stats) 145 + { 146 + fec_stats->corrected_blocks.total = 123; 147 + fec_stats->uncorrectable_blocks.total = 4; 148 + } 149 + 143 150 static int nsim_get_ts_info(struct net_device *dev, 144 151 struct ethtool_ts_info *info) 145 152 { ··· 170 163 .set_channels = nsim_set_channels, 171 164 .get_fecparam = nsim_get_fecparam, 172 165 .set_fecparam = nsim_set_fecparam, 166 + .get_fec_stats = nsim_get_fec_stats, 173 167 .get_ts_info = nsim_get_ts_info, 174 168 }; 175 169 ··· 189 181 ns->netdev->ethtool_ops = &nsim_ethtool_ops; 190 182 191 183 nsim_ethtool_ring_init(ns); 184 + 185 + ns->ethtool.pauseparam.report_stats_rx = true; 186 + ns->ethtool.pauseparam.report_stats_tx = true; 192 187 193 188 ns->ethtool.fec.fec = ETHTOOL_FEC_NONE; 194 189 ns->ethtool.fec.active_fec = ETHTOOL_FEC_NONE;
+49
drivers/net/netdevsim/netdev.c
··· 19 19 #include <linux/module.h> 20 20 #include <linux/netdevice.h> 21 21 #include <linux/slab.h> 22 + #include <net/netdev_queues.h> 22 23 #include <net/netlink.h> 23 24 #include <net/pkt_cls.h> 24 25 #include <net/rtnetlink.h> ··· 331 330 .ndo_set_features = nsim_set_features, 332 331 }; 333 332 333 + /* We don't have true per-queue stats, yet, so do some random fakery here. 334 + * Only report stuff for queue 0. 335 + */ 336 + static void nsim_get_queue_stats_rx(struct net_device *dev, int idx, 337 + struct netdev_queue_stats_rx *stats) 338 + { 339 + struct rtnl_link_stats64 rtstats = {}; 340 + 341 + if (!idx) 342 + nsim_get_stats64(dev, &rtstats); 343 + 344 + stats->packets = rtstats.rx_packets - !!rtstats.rx_packets; 345 + stats->bytes = rtstats.rx_bytes; 346 + } 347 + 348 + static void nsim_get_queue_stats_tx(struct net_device *dev, int idx, 349 + struct netdev_queue_stats_tx *stats) 350 + { 351 + struct rtnl_link_stats64 rtstats = {}; 352 + 353 + if (!idx) 354 + nsim_get_stats64(dev, &rtstats); 355 + 356 + stats->packets = rtstats.tx_packets - !!rtstats.tx_packets; 357 + stats->bytes = rtstats.tx_bytes; 358 + } 359 + 360 + static void nsim_get_base_stats(struct net_device *dev, 361 + struct netdev_queue_stats_rx *rx, 362 + struct netdev_queue_stats_tx *tx) 363 + { 364 + struct rtnl_link_stats64 rtstats = {}; 365 + 366 + nsim_get_stats64(dev, &rtstats); 367 + 368 + rx->packets = !!rtstats.rx_packets; 369 + rx->bytes = 0; 370 + tx->packets = !!rtstats.tx_packets; 371 + tx->bytes = 0; 372 + } 373 + 374 + static const struct netdev_stat_ops nsim_stat_ops = { 375 + .get_queue_stats_tx = nsim_get_queue_stats_tx, 376 + .get_queue_stats_rx = nsim_get_queue_stats_rx, 377 + .get_base_stats = nsim_get_base_stats, 378 + }; 379 + 334 380 static void nsim_setup(struct net_device *dev) 335 381 { 336 382 ether_setup(dev); ··· 408 360 409 361 ns->phc = phc; 410 362 ns->netdev->netdev_ops = &nsim_netdev_ops; 363 + ns->netdev->stat_ops = &nsim_stat_ops; 411 364 412 365 err = nsim_udp_tunnels_info_create(ns->nsim_dev, ns->netdev); 413 366 if (err)