[Intel-wired-lan] [PATCH net-next v5] ixgbe: implement get_queue_stats_rx

Kshitiz Bartariya via Intel-wired-lan <[email protected]>
Newsgroups org.osuosl.intel-wired-lan,org.kernel.vger.linux-kernel,org.kernel.vger.netdev
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)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.