]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ibmvnic: Use ndo_get_stats64 to fix inaccurate SAR reporting
authorMingming Cao <mmc@linux.ibm.com>
Wed, 16 Jul 2025 15:21:15 +0000 (11:21 -0400)
committerJakub Kicinski <kuba@kernel.org>
Fri, 18 Jul 2025 01:55:44 +0000 (18:55 -0700)
VNIC testing on multi-core Power systems showed SAR stats drift
and packet rate inconsistencies under load.

Implements ndo_get_stats64 to provide safe aggregation of queue-level
atomic64 counters into rtnl_link_stats64 for use by tools like 'ip -s',
'ifconfig', and 'sar'. Switch to ndo_get_stats64 to align SAR reporting
with the standard kernel interface for retrieving netdev stats.

This removes redundant per-adapter stat updates, reduces overhead,
eliminates cacheline bouncing from hot path updates, and improves
the accuracy of reported packet rates.

Signed-off-by: Mingming Cao <mmc@linux.ibm.com>
Reviewed-by: Brian King <bjking1@linux.ibm.com>
Reviewed-by: Dave Marquardt <davemarq@linux.ibm.com>
Reviewed-by: Simon Horman <horms@kernel.org>
----
Changes since v3:
link to v3: https://www.spinics.net/lists/netdev/msg1107999.html
-- keep per queue counters as u64 (this patch) and drop off patch 1 in v3

Link: https://patch.msgid.link/20250716152115.61143-1-mmc@linux.ibm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/ibm/ibmvnic.c

index 92647e137cf855bcc9bb6fe53c25acc780b66212..eec971567aacf446922ffebd5b66d87ea2a60d27 100644 (file)
@@ -2312,8 +2312,6 @@ static void ibmvnic_tx_scrq_clean_buffer(struct ibmvnic_adapter *adapter,
                                          tx_pool->num_buffers - 1 :
                                          tx_pool->consumer_index - 1;
                tx_buff = &tx_pool->tx_buff[index];
-               adapter->netdev->stats.tx_packets--;
-               adapter->netdev->stats.tx_bytes -= tx_buff->skb->len;
                adapter->tx_stats_buffers[queue_num].batched_packets--;
                adapter->tx_stats_buffers[queue_num].bytes -=
                                                tx_buff->skb->len;
@@ -2647,9 +2645,6 @@ tx_err:
        }
 out:
        rcu_read_unlock();
-       netdev->stats.tx_dropped += tx_dropped;
-       netdev->stats.tx_bytes += tx_bytes;
-       netdev->stats.tx_packets += tx_bpackets + tx_dpackets;
        adapter->tx_send_failed += tx_send_failed;
        adapter->tx_map_failed += tx_map_failed;
        adapter->tx_stats_buffers[queue_num].batched_packets += tx_bpackets;
@@ -3452,6 +3447,25 @@ err:
        return -ret;
 }
 
+static void ibmvnic_get_stats64(struct net_device *netdev,
+                               struct rtnl_link_stats64 *stats)
+{
+       struct ibmvnic_adapter *adapter = netdev_priv(netdev);
+       int i;
+
+       for (i = 0; i < adapter->req_rx_queues; i++) {
+               stats->rx_packets += adapter->rx_stats_buffers[i].packets;
+               stats->rx_bytes   += adapter->rx_stats_buffers[i].bytes;
+       }
+
+       for (i = 0; i < adapter->req_tx_queues; i++) {
+               stats->tx_packets += adapter->tx_stats_buffers[i].batched_packets;
+               stats->tx_packets += adapter->tx_stats_buffers[i].direct_packets;
+               stats->tx_bytes   += adapter->tx_stats_buffers[i].bytes;
+               stats->tx_dropped += adapter->tx_stats_buffers[i].dropped_packets;
+       }
+}
+
 static void ibmvnic_tx_timeout(struct net_device *dev, unsigned int txqueue)
 {
        struct ibmvnic_adapter *adapter = netdev_priv(dev);
@@ -3567,8 +3581,6 @@ restart_poll:
 
                length = skb->len;
                napi_gro_receive(napi, skb); /* send it up */
-               netdev->stats.rx_packets++;
-               netdev->stats.rx_bytes += length;
                adapter->rx_stats_buffers[scrq_num].packets++;
                adapter->rx_stats_buffers[scrq_num].bytes += length;
                frames_processed++;
@@ -3678,6 +3690,7 @@ static const struct net_device_ops ibmvnic_netdev_ops = {
        .ndo_set_rx_mode        = ibmvnic_set_multi,
        .ndo_set_mac_address    = ibmvnic_set_mac,
        .ndo_validate_addr      = eth_validate_addr,
+       .ndo_get_stats64        = ibmvnic_get_stats64,
        .ndo_tx_timeout         = ibmvnic_tx_timeout,
        .ndo_change_mtu         = ibmvnic_change_mtu,
        .ndo_features_check     = ibmvnic_features_check,