Commit 945c5704 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'ethtool-add-pause-frame-stats'



Jakub Kicinski says:

====================
ethtool: add pause frame stats

This is the first (small) series which exposes some stats via
the corresponding ethtool interface. Here (thanks to the
excitability of netlink) we expose pause frame stats via
the same interfaces as ethtool -a / -A.

In particular the following stats from the standard:
 - 30.3.4.2 aPAUSEMACCtrlFramesTransmitted
 - 30.3.4.3 aPAUSEMACCtrlFramesReceived

4 real drivers are converted, I believe we got confirmation
from maintainers that all exposed stats match the standard.

v3:
 - fix mlx5 build
 - adjust the init logic in patch 1
v2:
 - netdevsim: add missing static
 - bnxt: fix sparse warning
 - mlx5: address Saeed's comments
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 0f9ad4e7 12d342fe
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ the flags may not apply to requests. Recognized flags are:
  =================================  ===================================
  ``ETHTOOL_FLAG_COMPACT_BITSETS``   use compact format bitsets in reply
  ``ETHTOOL_FLAG_OMIT_REPLY``        omit optional reply (_SET and _ACT)
  ``ETHTOOL_FLAG_STATS``             include optional device statistics
  =================================  ===================================

New request flags should follow the general idea that if the flag is not set,
@@ -989,8 +990,18 @@ Kernel response contents:
  ``ETHTOOL_A_PAUSE_AUTONEG``            bool    pause autonegotiation
  ``ETHTOOL_A_PAUSE_RX``                 bool    receive pause frames
  ``ETHTOOL_A_PAUSE_TX``                 bool    transmit pause frames
  ``ETHTOOL_A_PAUSE_STATS``              nested  pause statistics
  =====================================  ======  ==========================

``ETHTOOL_A_PAUSE_STATS`` are reported if ``ETHTOOL_FLAG_STATS`` was set
in ``ETHTOOL_A_HEADER_FLAGS``.
It will be empty if driver did not report any statistics. Drivers fill in
the statistics in the following structure:

.. kernel-doc:: include/linux/ethtool.h
    :identifiers: ethtool_pause_stats

Each member has a corresponding attribute defined.

PAUSE_SET
============
+52 −5
Original line number Diff line number Diff line
@@ -4,16 +4,23 @@
Interface statistics
====================

Overview
========

This document is a guide to Linux network interface statistics.

There are two main sources of interface statistics in Linux:
There are three main sources of interface statistics in Linux:

 - standard interface statistics based on
   :c:type:`struct rtnl_link_stats64 <rtnl_link_stats64>`; and
   :c:type:`struct rtnl_link_stats64 <rtnl_link_stats64>`;
 - protocol-specific statistics; and
 - driver-defined statistics available via ethtool.

There are multiple interfaces to reach the former. Most commonly used
is the `ip` command from `iproute2`::
Standard interface statistics
-----------------------------

There are multiple interfaces to reach the standard statistics.
Most commonly used is the `ip` command from `iproute2`::

  $ ip -s -s link show dev ens4u1u1
  6: ens4u1u1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
@@ -34,7 +41,26 @@ If `-s` is specified once the detailed errors won't be shown.

`ip` supports JSON formatting via the `-j` option.

Ethtool statistics can be dumped using `ethtool -S $ifc`, e.g.::
Protocol-specific statistics
----------------------------

Some of the interfaces used for configuring devices are also able
to report related statistics. For example ethtool interface used
to configure pause frames can report corresponding hardware counters::

  $ ethtool --include-statistics -a eth0
  Pause parameters for eth0:
  Autonegotiate:	on
  RX:			on
  TX:			on
  Statistics:
    tx_pause_frames: 1
    rx_pause_frames: 1

Driver-defined statistics
-------------------------

Driver-defined ethtool statistics can be dumped using `ethtool -S $ifc`, e.g.::

  $ ethtool -S ens4u1u1
  NIC statistics:
@@ -94,6 +120,17 @@ Identifiers via `ETHTOOL_GSTRINGS` with `string_set` set to `ETH_SS_STATS`,
and values via `ETHTOOL_GSTATS`. User space should use `ETHTOOL_GDRVINFO`
to retrieve the number of statistics (`.n_stats`).

ethtool-netlink
---------------

Ethtool netlink is a replacement for the older IOCTL interface.

Protocol-related statistics can be requested in get commands by setting
the `ETHTOOL_FLAG_STATS` flag in `ETHTOOL_A_HEADER_FLAGS`. Currently
statistics are supported in the following commands:

  - `ETHTOOL_MSG_PAUSE_GET`

debugfs
-------

@@ -130,3 +167,13 @@ user space trying to read them.

Statistics must persist across routine operations like bringing the interface
down and up.

Kernel-internal data structures
-------------------------------

The following structures are internal to the kernel, their members are
translated to netlink attributes when dumped. Drivers must not overwrite
the statistics they don't report with 0.

.. kernel-doc:: include/linux/ethtool.h
    :identifiers: ethtool_pause_stats
+17 −0
Original line number Diff line number Diff line
@@ -1778,6 +1778,22 @@ static void bnxt_get_pauseparam(struct net_device *dev,
	epause->tx_pause = !!(link_info->req_flow_ctrl & BNXT_LINK_PAUSE_TX);
}

static void bnxt_get_pause_stats(struct net_device *dev,
				 struct ethtool_pause_stats *epstat)
{
	struct bnxt *bp = netdev_priv(dev);
	u64 *rx, *tx;

	if (BNXT_VF(bp) || !(bp->flags & BNXT_FLAG_PORT_STATS))
		return;

	rx = bp->port_stats.sw_stats;
	tx = bp->port_stats.sw_stats + BNXT_TX_PORT_STATS_BYTE_OFFSET / 8;

	epstat->rx_pause_frames = BNXT_GET_RX_PORT_STATS64(rx, rx_pause_frames);
	epstat->tx_pause_frames = BNXT_GET_TX_PORT_STATS64(tx, tx_pause_frames);
}

static int bnxt_set_pauseparam(struct net_device *dev,
			       struct ethtool_pauseparam *epause)
{
@@ -3645,6 +3661,7 @@ const struct ethtool_ops bnxt_ethtool_ops = {
				     ETHTOOL_COALESCE_USE_ADAPTIVE_RX,
	.get_link_ksettings	= bnxt_get_link_ksettings,
	.set_link_ksettings	= bnxt_set_link_ksettings,
	.get_pause_stats	= bnxt_get_pause_stats,
	.get_pauseparam		= bnxt_get_pauseparam,
	.set_pauseparam		= bnxt_set_pauseparam,
	.get_drvinfo		= bnxt_get_drvinfo,
+11 −0
Original line number Diff line number Diff line
@@ -531,6 +531,16 @@ static int ixgbe_set_link_ksettings(struct net_device *netdev,
	return err;
}

static void ixgbe_get_pause_stats(struct net_device *netdev,
				  struct ethtool_pause_stats *stats)
{
	struct ixgbe_adapter *adapter = netdev_priv(netdev);
	struct ixgbe_hw_stats *hwstats = &adapter->stats;

	stats->tx_pause_frames = hwstats->lxontxc + hwstats->lxofftxc;
	stats->rx_pause_frames = hwstats->lxonrxc + hwstats->lxoffrxc;
}

static void ixgbe_get_pauseparam(struct net_device *netdev,
				 struct ethtool_pauseparam *pause)
{
@@ -3546,6 +3556,7 @@ static const struct ethtool_ops ixgbe_ethtool_ops = {
	.set_eeprom             = ixgbe_set_eeprom,
	.get_ringparam          = ixgbe_get_ringparam,
	.set_ringparam          = ixgbe_set_ringparam,
	.get_pause_stats	= ixgbe_get_pause_stats,
	.get_pauseparam         = ixgbe_get_pauseparam,
	.set_pauseparam         = ixgbe_set_pauseparam,
	.get_msglevel           = ixgbe_get_msglevel,
+19 −0
Original line number Diff line number Diff line
@@ -1106,6 +1106,24 @@ static int mlx4_en_set_pauseparam(struct net_device *dev,
	return err;
}

static void mlx4_en_get_pause_stats(struct net_device *dev,
				    struct ethtool_pause_stats *stats)
{
	struct mlx4_en_priv *priv = netdev_priv(dev);
	struct bitmap_iterator it;

	bitmap_iterator_init(&it, priv->stats_bitmap.bitmap, NUM_ALL_STATS);

	spin_lock_bh(&priv->stats_lock);
	if (test_bit(FLOW_PRIORITY_STATS_IDX_TX_FRAMES,
		     priv->stats_bitmap.bitmap))
		stats->tx_pause_frames = priv->tx_flowstats.tx_pause;
	if (test_bit(FLOW_PRIORITY_STATS_IDX_RX_FRAMES,
		     priv->stats_bitmap.bitmap))
		stats->rx_pause_frames = priv->rx_flowstats.rx_pause;
	spin_unlock_bh(&priv->stats_lock);
}

static void mlx4_en_get_pauseparam(struct net_device *dev,
				 struct ethtool_pauseparam *pause)
{
@@ -2138,6 +2156,7 @@ const struct ethtool_ops mlx4_en_ethtool_ops = {
	.set_msglevel = mlx4_en_set_msglevel,
	.get_coalesce = mlx4_en_get_coalesce,
	.set_coalesce = mlx4_en_set_coalesce,
	.get_pause_stats = mlx4_en_get_pause_stats,
	.get_pauseparam = mlx4_en_get_pauseparam,
	.set_pauseparam = mlx4_en_set_pauseparam,
	.get_ringparam = mlx4_en_get_ringparam,
Loading