STRUCT NETDEV_STAT_OPS(9)
πΈ struct netdev_stat_ops(9) πΈ
okay so bestie, welcome to the Kernel API Manual β this is the page for struct netdev_stat_ops, and it's literally the blueprint for getting fine-grained stats out of your netdev. let's get into it π
β¨ NAME β¨
struct netdev_stat_ops β netdev ops for fine grained stats. that's it, that's the vibe π
π¦ SYNOPSIS π¦
struct netdev_stat_ops {
void (*get_queue_stats_rx)(struct net_device *dev, int idx, struct
netdev_queue_stats_rx *stats);
void (*get_queue_stats_tx)(struct net_device *dev, int idx, struct
netdev_queue_stats_tx *stats);
void (*get_base_stats)(struct net_device *dev, struct
netdev_queue_stats_rx *rx, struct netdev_queue_stats_tx *tx);
};
π Members π
get_queue_stats_rxβ grab the stats for one specific Rx queue, periodt πget_queue_stats_txβ same deal but for a given Tx queue, no cap β¨get_base_statsβ get the base stats, aka the ones that don't belong to any live instance π
π₯ Description π₯
So like, the whole point is you're querying stats for a given object. and here's the crucial part bestie β the values of the statistics are undefined on entry, and yes, specifically they are not zero-initialized π so don't go assuming. Drivers should assign values only to the statistics they actually collect. anything you don't collect? leave it undefined, don't touch it, hands off π
Queue objects are not necessarily persistent, okay? only the currently active queues get queried by the per-queue callbacks. which means per-queue statistics will not generally add up to the total number of events for the device β it's giving "close but not the whole story". that's exactly where the get_base_stats callback comes in: it lets you fill in the delta between the events for currently live queues and the overall device history. get_base_stats can also be used to report any miscellaneous packets transferred outside of the main set of queues used by the networking stack. iconic multitasking honestly π«Ά
Now, when the statistics for the entire device are queried, the order goes like this: first get_base_stats is issued to collect the delta, then a series of per-queue callbacks. Slay. And here's the twist β only statistics which are set in get_base_stats will be reported at the device level. Meaning that, unlike in queue callbacks, setting a statistic to zero in get_base_stats is a totally legitimate thing to do β this is because get_base_stats has a second function: designating which statistics are in fact correct for the entire device (think: when history for some of the events is not maintained, and a reliable "total" cannot be provided β yeah, in that case you genuinely can't give one, and that's fine).
Ops are called under the instance lock if netdev_need_ops_lock returns true, otherwise under rtnl_lock. Device drivers can assume that when collecting total device stats, the get_base_stats and subsequent per-queue calls are performed "atomically" (without releasing the relevant lock). π so like, don't worry about the lock slipping away mid-collection mid-character-energy.
π One thing drivers are encouraged to do: reset the per-queue statistics when the number of queues changes. Why? because the primary use case for per-queue statistics is currently to detect traffic imbalance β and stale numbers would absolutely ruin that vibe check.
π SEE ALSO π
- Kernel file
./include/net/netdev_queues.h struct netdev_config(9)struct netdev_queue_mgmt_ops(9)- Lockless queue stopping / waking helpers.(9)
netif_txq_maybe_stop(9)__netif_txq_completed_wake(9)
okay that's the whole page, you ate that π
π this one came out of ./include/net β the Kernel API Manual source β dated October 2026. go forth and collect your fine-grained stats, bestie, ily π§β¨π
π¦ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms