[PATCH net-next v5] ixgbe: implement get_queue_stats_rx
Kshitiz Bartariya <[email protected]>
| Newsgroups | org.kernel.vger.netdev,org.kernel.vger.linux-kernel,org.osuosl.intel-wired-lan |
|---|---|
| Message-ID | <[email protected]> |
Hook into the netdev_stat_ops interface to expose per RX queue statistics through the netdev generic netlink API. The following counters are filled: - bytes: maps directly to bytes - packets: maps directly to packets - alloc_fail: sum of alloc_rx_page_failed and alloc_rx_buff_failed - csum_bad: maps directly to csum_err, which is incremented for both IP header and L4 checksum errors in ixgbe_rx_checksum(). The new per-queue stats can be observed with: $ ynltool qstats show scope queue Signed-off-by: Kshitiz Bartariya <[email protected]> --- v5: - Added READ_ONCE() and NULL check for accessing adapter->rx_ring[i] - Added u64_stats_fetch_begin before reading stats from rx_ring Suggested by Simon Horman v4: - Changed comment format from // to /* */ - Moved ixgbe_stat_ops declaration next to the ixgbe_netdev_ops Suggested by Jedrzej Jagielski. https://lore.kernel.org/lkml/[email protected]/ v3: - Added bytes and packets stats counters - Implemented ixgbe_get_base_stats function As suggested by AI on https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260603174857.78666-1-kshitiz.bartariya%40zohomail.in https://lore.kernel.org/lkml/[email protected]/ v2: Amended commit message with command to get RX queue stats as suggested by Jedrzej Jagielski. https://lore.kernel.org/lkml/[email protected]/ v1: https://lore.kernel.org/lkml/[email protected]/ drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 8873a8cc4a18..560177f135ff 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -9760,6 +9760,45 @@ static void ixgbe_get_stats64(struct net_device *netdev, stats->rx_missed_errors = netdev->stats.rx_missed_errors; } +static void ixgbe_get_queue_stats_rx(struct net_device *dev, int idx, + struct netdev_queue_stats_rx *stats) +{ + struct ixgbe_adapter *adapter = ixgbe_from_netdev(dev); + struct ixgbe_ring *ring = READ_ONCE(adapter->rx_ring[idx]); + u64 bytes, packets, alloc_rx_page_failed, alloc_rx_buff_failed, + csum_err; + unsigned int start; + + if (ring) { + do { + start = u64_stats_fetch_begin(&ring->syncp); + bytes = ring->stats.bytes; + packets = ring->stats.packets; + alloc_rx_page_failed = + ring->rx_stats.alloc_rx_page_failed; + alloc_rx_buff_failed = + ring->rx_stats.alloc_rx_buff_failed; + csum_err = ring->rx_stats.csum_err; + } while (u64_stats_fetch_retry(&ring->syncp, start)); + } + + stats->bytes = bytes; + stats->packets = packets; + stats->alloc_fail = alloc_rx_page_failed + alloc_rx_buff_failed; + stats->csum_bad = csum_err; +} + +static void ixgbe_get_base_stats(struct net_device *dev, + struct netdev_queue_stats_rx *rx, + struct netdev_queue_stats_tx *tx) +{ + /* ixgbe has no inactive queues */ + rx->bytes = 0; + rx->packets = 0; + rx->alloc_fail = 0; + rx->csum_bad = 0; +} + static int ixgbe_ndo_get_vf_stats(struct net_device *netdev, int vf, struct ifla_vf_stats *vf_stats) { @@ -11117,6 +11156,11 @@ static const struct net_device_ops ixgbe_netdev_ops = { .ndo_hwtstamp_set = ixgbe_ptp_hwtstamp_set, }; +static const struct netdev_stat_ops ixgbe_stat_ops = { + .get_queue_stats_rx = ixgbe_get_queue_stats_rx, + .get_base_stats = ixgbe_get_base_stats, +}; + static void ixgbe_disable_txr_hw(struct ixgbe_adapter *adapter, struct ixgbe_ring *tx_ring) { @@ -11663,6 +11707,7 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) hw->phy.mdio.mdio_write = ixgbe_mdio_write; netdev->netdev_ops = &ixgbe_netdev_ops; + netdev->stat_ops = &ixgbe_stat_ops; ixgbe_set_ethtool_ops(netdev); netdev->watchdog_timeo = 5 * HZ; strscpy(netdev->name, pci_name(pdev), sizeof(netdev->name)); -- 2.50.1 (Apple Git-155)