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

Configure Feed

Select the types of activity you want to include in your feed.

ibmvnic: Use ndo_get_stats64 to fix inaccurate SAR reporting

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>

authored by

Mingming Cao and committed by
Jakub Kicinski
efe28034 0dce6847

+20 -7
+20 -7
drivers/net/ethernet/ibm/ibmvnic.c
··· 2312 2312 tx_pool->num_buffers - 1 : 2313 2313 tx_pool->consumer_index - 1; 2314 2314 tx_buff = &tx_pool->tx_buff[index]; 2315 - adapter->netdev->stats.tx_packets--; 2316 - adapter->netdev->stats.tx_bytes -= tx_buff->skb->len; 2317 2315 adapter->tx_stats_buffers[queue_num].batched_packets--; 2318 2316 adapter->tx_stats_buffers[queue_num].bytes -= 2319 2317 tx_buff->skb->len; ··· 2645 2647 } 2646 2648 out: 2647 2649 rcu_read_unlock(); 2648 - netdev->stats.tx_dropped += tx_dropped; 2649 - netdev->stats.tx_bytes += tx_bytes; 2650 - netdev->stats.tx_packets += tx_bpackets + tx_dpackets; 2651 2650 adapter->tx_send_failed += tx_send_failed; 2652 2651 adapter->tx_map_failed += tx_map_failed; 2653 2652 adapter->tx_stats_buffers[queue_num].batched_packets += tx_bpackets; ··· 3447 3452 return -ret; 3448 3453 } 3449 3454 3455 + static void ibmvnic_get_stats64(struct net_device *netdev, 3456 + struct rtnl_link_stats64 *stats) 3457 + { 3458 + struct ibmvnic_adapter *adapter = netdev_priv(netdev); 3459 + int i; 3460 + 3461 + for (i = 0; i < adapter->req_rx_queues; i++) { 3462 + stats->rx_packets += adapter->rx_stats_buffers[i].packets; 3463 + stats->rx_bytes += adapter->rx_stats_buffers[i].bytes; 3464 + } 3465 + 3466 + for (i = 0; i < adapter->req_tx_queues; i++) { 3467 + stats->tx_packets += adapter->tx_stats_buffers[i].batched_packets; 3468 + stats->tx_packets += adapter->tx_stats_buffers[i].direct_packets; 3469 + stats->tx_bytes += adapter->tx_stats_buffers[i].bytes; 3470 + stats->tx_dropped += adapter->tx_stats_buffers[i].dropped_packets; 3471 + } 3472 + } 3473 + 3450 3474 static void ibmvnic_tx_timeout(struct net_device *dev, unsigned int txqueue) 3451 3475 { 3452 3476 struct ibmvnic_adapter *adapter = netdev_priv(dev); ··· 3581 3567 3582 3568 length = skb->len; 3583 3569 napi_gro_receive(napi, skb); /* send it up */ 3584 - netdev->stats.rx_packets++; 3585 - netdev->stats.rx_bytes += length; 3586 3570 adapter->rx_stats_buffers[scrq_num].packets++; 3587 3571 adapter->rx_stats_buffers[scrq_num].bytes += length; 3588 3572 frames_processed++; ··· 3690 3678 .ndo_set_rx_mode = ibmvnic_set_multi, 3691 3679 .ndo_set_mac_address = ibmvnic_set_mac, 3692 3680 .ndo_validate_addr = eth_validate_addr, 3681 + .ndo_get_stats64 = ibmvnic_get_stats64, 3693 3682 .ndo_tx_timeout = ibmvnic_tx_timeout, 3694 3683 .ndo_change_mtu = ibmvnic_change_mtu, 3695 3684 .ndo_features_check = ibmvnic_features_check,