Skip to content

Commit 4197aa7

Browse files
Eric DumazetJeff Kirsher
authored andcommitted
ixgbevf: provide 64 bit statistics
Compute statistics per ring using 64 bits, and provide network device stats in 64 bits. It should make this driver multiqueue operations faster (no more cache line ping pongs on netdev->stats structure) Use u64_stats_sync infrastructure so that its safe on 32bit arches as well. Based on a prior patch from Stephen Hemminger Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> CC: Stephen Hemminger <shemminger@vyatta.com> Acked-by: Greg Rose <gregory.v.rose@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
1 parent 98b9e48 commit 4197aa7

File tree

2 files changed

+48
-12
lines changed

2 files changed

+48
-12
lines changed

drivers/net/ethernet/intel/ixgbevf/ixgbevf.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <linux/io.h>
3535
#include <linux/netdevice.h>
3636
#include <linux/if_vlan.h>
37+
#include <linux/u64_stats_sync.h>
3738

3839
#include "vf.h"
3940

@@ -71,12 +72,13 @@ struct ixgbevf_ring {
7172
struct ixgbevf_rx_buffer *rx_buffer_info;
7273
};
7374

75+
u64 total_bytes;
76+
u64 total_packets;
77+
struct u64_stats_sync syncp;
78+
7479
u16 head;
7580
u16 tail;
7681

77-
unsigned int total_bytes;
78-
unsigned int total_packets;
79-
8082
u16 reg_idx; /* holds the special value that gets the hardware register
8183
* offset associated with this ring, which is different
8284
* for DCB and RSS modes */

drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -270,11 +270,10 @@ static bool ixgbevf_clean_tx_irq(struct ixgbevf_adapter *adapter,
270270
IXGBE_WRITE_REG(hw, IXGBE_VTEICS, tx_ring->v_idx);
271271
}
272272

273+
u64_stats_update_begin(&tx_ring->syncp);
273274
tx_ring->total_bytes += total_bytes;
274275
tx_ring->total_packets += total_packets;
275-
276-
netdev->stats.tx_bytes += total_bytes;
277-
netdev->stats.tx_packets += total_packets;
276+
u64_stats_update_end(&tx_ring->syncp);
278277

279278
return count < tx_ring->work_limit;
280279
}
@@ -597,10 +596,10 @@ static bool ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector,
597596
if (cleaned_count)
598597
ixgbevf_alloc_rx_buffers(adapter, rx_ring, cleaned_count);
599598

599+
u64_stats_update_begin(&rx_ring->syncp);
600600
rx_ring->total_packets += total_rx_packets;
601601
rx_ring->total_bytes += total_rx_bytes;
602-
adapter->netdev->stats.rx_bytes += total_rx_bytes;
603-
adapter->netdev->stats.rx_packets += total_rx_packets;
602+
u64_stats_update_end(&rx_ring->syncp);
604603

605604
return cleaned;
606605
}
@@ -2260,10 +2259,6 @@ void ixgbevf_update_stats(struct ixgbevf_adapter *adapter)
22602259
adapter->stats.vfgotc);
22612260
UPDATE_VF_COUNTER_32bit(IXGBE_VFMPRC, adapter->stats.last_vfmprc,
22622261
adapter->stats.vfmprc);
2263-
2264-
/* Fill out the OS statistics structure */
2265-
adapter->netdev->stats.multicast = adapter->stats.vfmprc -
2266-
adapter->stats.base_vfmprc;
22672262
}
22682263

22692264
/**
@@ -3220,11 +3215,50 @@ static void ixgbevf_shutdown(struct pci_dev *pdev)
32203215
pci_disable_device(pdev);
32213216
}
32223217

3218+
static struct rtnl_link_stats64 *ixgbevf_get_stats(struct net_device *netdev,
3219+
struct rtnl_link_stats64 *stats)
3220+
{
3221+
struct ixgbevf_adapter *adapter = netdev_priv(netdev);
3222+
unsigned int start;
3223+
u64 bytes, packets;
3224+
const struct ixgbevf_ring *ring;
3225+
int i;
3226+
3227+
ixgbevf_update_stats(adapter);
3228+
3229+
stats->multicast = adapter->stats.vfmprc - adapter->stats.base_vfmprc;
3230+
3231+
for (i = 0; i < adapter->num_rx_queues; i++) {
3232+
ring = &adapter->rx_ring[i];
3233+
do {
3234+
start = u64_stats_fetch_begin_bh(&ring->syncp);
3235+
bytes = ring->total_bytes;
3236+
packets = ring->total_packets;
3237+
} while (u64_stats_fetch_retry_bh(&ring->syncp, start));
3238+
stats->rx_bytes += bytes;
3239+
stats->rx_packets += packets;
3240+
}
3241+
3242+
for (i = 0; i < adapter->num_tx_queues; i++) {
3243+
ring = &adapter->tx_ring[i];
3244+
do {
3245+
start = u64_stats_fetch_begin_bh(&ring->syncp);
3246+
bytes = ring->total_bytes;
3247+
packets = ring->total_packets;
3248+
} while (u64_stats_fetch_retry_bh(&ring->syncp, start));
3249+
stats->tx_bytes += bytes;
3250+
stats->tx_packets += packets;
3251+
}
3252+
3253+
return stats;
3254+
}
3255+
32233256
static const struct net_device_ops ixgbe_netdev_ops = {
32243257
.ndo_open = ixgbevf_open,
32253258
.ndo_stop = ixgbevf_close,
32263259
.ndo_start_xmit = ixgbevf_xmit_frame,
32273260
.ndo_set_rx_mode = ixgbevf_set_rx_mode,
3261+
.ndo_get_stats64 = ixgbevf_get_stats,
32283262
.ndo_validate_addr = eth_validate_addr,
32293263
.ndo_set_mac_address = ixgbevf_set_mac,
32303264
.ndo_change_mtu = ixgbevf_change_mtu,

0 commit comments

Comments
 (0)