summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn Töpel <bjorn.topel@intel.com>2018-08-24 13:21:59 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-03-19 13:12:42 +0100
commit090ce34b7832c5e450e13847876832c2870bbc63 (patch)
tree3c1893d9cd9752d0b430d2a64f24a803ffbc217c
parenteab8018fd289304c742212cbdcecc2e08716ba83 (diff)
downloadlinux-stable-090ce34b7832c5e450e13847876832c2870bbc63.tar.gz
linux-stable-090ce34b7832c5e450e13847876832c2870bbc63.tar.bz2
linux-stable-090ce34b7832c5e450e13847876832c2870bbc63.zip
i40e: report correct statistics when XDP is enabled
commit cdec2141c24ef177d929765c5a6f95549c266fb3 upstream. When XDP is enabled, the driver will report incorrect statistics. Received frames will reported as transmitted frames. This commits fixes the i40e implementation of ndo_get_stats64 (struct net_device_ops), so that iproute2 will report correct statistics (e.g. when running "ip -stats link show dev eth0") even when XDP is enabled. Reported-by: Jesper Dangaard Brouer <brouer@redhat.com> Fixes: 74608d17fe29 ("i40e: add support for XDP_TX action") Signed-off-by: Björn Töpel <bjorn.topel@intel.com> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Cc: Emeric Brun <ebrun@haproxy.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_main.c24
1 files changed, 13 insertions, 11 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 41fa22c562c1..f81ad0aa8b09 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -424,9 +424,9 @@ static void i40e_get_netdev_stats_struct(struct net_device *netdev,
struct rtnl_link_stats64 *stats)
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
- struct i40e_ring *tx_ring, *rx_ring;
struct i40e_vsi *vsi = np->vsi;
struct rtnl_link_stats64 *vsi_stats = i40e_get_vsi_stats_struct(vsi);
+ struct i40e_ring *ring;
int i;
if (test_bit(__I40E_VSI_DOWN, vsi->state))
@@ -440,24 +440,26 @@ static void i40e_get_netdev_stats_struct(struct net_device *netdev,
u64 bytes, packets;
unsigned int start;
- tx_ring = READ_ONCE(vsi->tx_rings[i]);
- if (!tx_ring)
+ ring = READ_ONCE(vsi->tx_rings[i]);
+ if (!ring)
continue;
- i40e_get_netdev_stats_struct_tx(tx_ring, stats);
+ i40e_get_netdev_stats_struct_tx(ring, stats);
- rx_ring = &tx_ring[1];
+ if (i40e_enabled_xdp_vsi(vsi)) {
+ ring++;
+ i40e_get_netdev_stats_struct_tx(ring, stats);
+ }
+ ring++;
do {
- start = u64_stats_fetch_begin_irq(&rx_ring->syncp);
- packets = rx_ring->stats.packets;
- bytes = rx_ring->stats.bytes;
- } while (u64_stats_fetch_retry_irq(&rx_ring->syncp, start));
+ start = u64_stats_fetch_begin_irq(&ring->syncp);
+ packets = ring->stats.packets;
+ bytes = ring->stats.bytes;
+ } while (u64_stats_fetch_retry_irq(&ring->syncp, start));
stats->rx_packets += packets;
stats->rx_bytes += bytes;
- if (i40e_enabled_xdp_vsi(vsi))
- i40e_get_netdev_stats_struct_tx(&rx_ring[1], stats);
}
rcu_read_unlock();