Skip to content

Commit 945c570

Browse files
committed
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: David S. Miller <[email protected]>
2 parents 0f9ad4e + 12d342f commit 945c570

File tree

18 files changed

+462
-8
lines changed

18 files changed

+462
-8
lines changed

Documentation/networking/ethtool-netlink.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ the flags may not apply to requests. Recognized flags are:
6868
================================= ===================================
6969
``ETHTOOL_FLAG_COMPACT_BITSETS`` use compact format bitsets in reply
7070
``ETHTOOL_FLAG_OMIT_REPLY`` omit optional reply (_SET and _ACT)
71+
``ETHTOOL_FLAG_STATS`` include optional device statistics
7172
================================= ===================================
7273

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

996+
``ETHTOOL_A_PAUSE_STATS`` are reported if ``ETHTOOL_FLAG_STATS`` was set
997+
in ``ETHTOOL_A_HEADER_FLAGS``.
998+
It will be empty if driver did not report any statistics. Drivers fill in
999+
the statistics in the following structure:
1000+
1001+
.. kernel-doc:: include/linux/ethtool.h
1002+
:identifiers: ethtool_pause_stats
1003+
1004+
Each member has a corresponding attribute defined.
9941005

9951006
PAUSE_SET
9961007
============

Documentation/networking/statistics.rst

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,23 @@
44
Interface statistics
55
====================
66

7+
Overview
8+
========
9+
710
This document is a guide to Linux network interface statistics.
811

9-
There are two main sources of interface statistics in Linux:
12+
There are three main sources of interface statistics in Linux:
1013

1114
- standard interface statistics based on
12-
:c:type:`struct rtnl_link_stats64 <rtnl_link_stats64>`; and
15+
:c:type:`struct rtnl_link_stats64 <rtnl_link_stats64>`;
16+
- protocol-specific statistics; and
1317
- driver-defined statistics available via ethtool.
1418

15-
There are multiple interfaces to reach the former. Most commonly used
16-
is the `ip` command from `iproute2`::
19+
Standard interface statistics
20+
-----------------------------
21+
22+
There are multiple interfaces to reach the standard statistics.
23+
Most commonly used is the `ip` command from `iproute2`::
1724

1825
$ ip -s -s link show dev ens4u1u1
1926
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.
3441

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

37-
Ethtool statistics can be dumped using `ethtool -S $ifc`, e.g.::
44+
Protocol-specific statistics
45+
----------------------------
46+
47+
Some of the interfaces used for configuring devices are also able
48+
to report related statistics. For example ethtool interface used
49+
to configure pause frames can report corresponding hardware counters::
50+
51+
$ ethtool --include-statistics -a eth0
52+
Pause parameters for eth0:
53+
Autonegotiate: on
54+
RX: on
55+
TX: on
56+
Statistics:
57+
tx_pause_frames: 1
58+
rx_pause_frames: 1
59+
60+
Driver-defined statistics
61+
-------------------------
62+
63+
Driver-defined ethtool statistics can be dumped using `ethtool -S $ifc`, e.g.::
3864

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

123+
ethtool-netlink
124+
---------------
125+
126+
Ethtool netlink is a replacement for the older IOCTL interface.
127+
128+
Protocol-related statistics can be requested in get commands by setting
129+
the `ETHTOOL_FLAG_STATS` flag in `ETHTOOL_A_HEADER_FLAGS`. Currently
130+
statistics are supported in the following commands:
131+
132+
- `ETHTOOL_MSG_PAUSE_GET`
133+
97134
debugfs
98135
-------
99136

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

131168
Statistics must persist across routine operations like bringing the interface
132169
down and up.
170+
171+
Kernel-internal data structures
172+
-------------------------------
173+
174+
The following structures are internal to the kernel, their members are
175+
translated to netlink attributes when dumped. Drivers must not overwrite
176+
the statistics they don't report with 0.
177+
178+
.. kernel-doc:: include/linux/ethtool.h
179+
:identifiers: ethtool_pause_stats

drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1778,6 +1778,22 @@ static void bnxt_get_pauseparam(struct net_device *dev,
17781778
epause->tx_pause = !!(link_info->req_flow_ctrl & BNXT_LINK_PAUSE_TX);
17791779
}
17801780

1781+
static void bnxt_get_pause_stats(struct net_device *dev,
1782+
struct ethtool_pause_stats *epstat)
1783+
{
1784+
struct bnxt *bp = netdev_priv(dev);
1785+
u64 *rx, *tx;
1786+
1787+
if (BNXT_VF(bp) || !(bp->flags & BNXT_FLAG_PORT_STATS))
1788+
return;
1789+
1790+
rx = bp->port_stats.sw_stats;
1791+
tx = bp->port_stats.sw_stats + BNXT_TX_PORT_STATS_BYTE_OFFSET / 8;
1792+
1793+
epstat->rx_pause_frames = BNXT_GET_RX_PORT_STATS64(rx, rx_pause_frames);
1794+
epstat->tx_pause_frames = BNXT_GET_TX_PORT_STATS64(tx, tx_pause_frames);
1795+
}
1796+
17811797
static int bnxt_set_pauseparam(struct net_device *dev,
17821798
struct ethtool_pauseparam *epause)
17831799
{
@@ -3645,6 +3661,7 @@ const struct ethtool_ops bnxt_ethtool_ops = {
36453661
ETHTOOL_COALESCE_USE_ADAPTIVE_RX,
36463662
.get_link_ksettings = bnxt_get_link_ksettings,
36473663
.set_link_ksettings = bnxt_set_link_ksettings,
3664+
.get_pause_stats = bnxt_get_pause_stats,
36483665
.get_pauseparam = bnxt_get_pauseparam,
36493666
.set_pauseparam = bnxt_set_pauseparam,
36503667
.get_drvinfo = bnxt_get_drvinfo,

drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,16 @@ static int ixgbe_set_link_ksettings(struct net_device *netdev,
531531
return err;
532532
}
533533

534+
static void ixgbe_get_pause_stats(struct net_device *netdev,
535+
struct ethtool_pause_stats *stats)
536+
{
537+
struct ixgbe_adapter *adapter = netdev_priv(netdev);
538+
struct ixgbe_hw_stats *hwstats = &adapter->stats;
539+
540+
stats->tx_pause_frames = hwstats->lxontxc + hwstats->lxofftxc;
541+
stats->rx_pause_frames = hwstats->lxonrxc + hwstats->lxoffrxc;
542+
}
543+
534544
static void ixgbe_get_pauseparam(struct net_device *netdev,
535545
struct ethtool_pauseparam *pause)
536546
{
@@ -3546,6 +3556,7 @@ static const struct ethtool_ops ixgbe_ethtool_ops = {
35463556
.set_eeprom = ixgbe_set_eeprom,
35473557
.get_ringparam = ixgbe_get_ringparam,
35483558
.set_ringparam = ixgbe_set_ringparam,
3559+
.get_pause_stats = ixgbe_get_pause_stats,
35493560
.get_pauseparam = ixgbe_get_pauseparam,
35503561
.set_pauseparam = ixgbe_set_pauseparam,
35513562
.get_msglevel = ixgbe_get_msglevel,

drivers/net/ethernet/mellanox/mlx4/en_ethtool.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,6 +1106,24 @@ static int mlx4_en_set_pauseparam(struct net_device *dev,
11061106
return err;
11071107
}
11081108

1109+
static void mlx4_en_get_pause_stats(struct net_device *dev,
1110+
struct ethtool_pause_stats *stats)
1111+
{
1112+
struct mlx4_en_priv *priv = netdev_priv(dev);
1113+
struct bitmap_iterator it;
1114+
1115+
bitmap_iterator_init(&it, priv->stats_bitmap.bitmap, NUM_ALL_STATS);
1116+
1117+
spin_lock_bh(&priv->stats_lock);
1118+
if (test_bit(FLOW_PRIORITY_STATS_IDX_TX_FRAMES,
1119+
priv->stats_bitmap.bitmap))
1120+
stats->tx_pause_frames = priv->tx_flowstats.tx_pause;
1121+
if (test_bit(FLOW_PRIORITY_STATS_IDX_RX_FRAMES,
1122+
priv->stats_bitmap.bitmap))
1123+
stats->rx_pause_frames = priv->rx_flowstats.rx_pause;
1124+
spin_unlock_bh(&priv->stats_lock);
1125+
}
1126+
11091127
static void mlx4_en_get_pauseparam(struct net_device *dev,
11101128
struct ethtool_pauseparam *pause)
11111129
{
@@ -2138,6 +2156,7 @@ const struct ethtool_ops mlx4_en_ethtool_ops = {
21382156
.set_msglevel = mlx4_en_set_msglevel,
21392157
.get_coalesce = mlx4_en_get_coalesce,
21402158
.set_coalesce = mlx4_en_set_coalesce,
2159+
.get_pause_stats = mlx4_en_get_pause_stats,
21412160
.get_pauseparam = mlx4_en_get_pauseparam,
21422161
.set_pauseparam = mlx4_en_set_pauseparam,
21432162
.get_ringparam = mlx4_en_get_ringparam,

drivers/net/ethernet/mellanox/mlx4/mlx4_stats.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ struct mlx4_en_flow_stats_rx {
8484
MLX4_NUM_PRIORITIES)
8585
};
8686

87+
#define FLOW_PRIORITY_STATS_IDX_RX_FRAMES (NUM_MAIN_STATS + \
88+
NUM_PORT_STATS + \
89+
NUM_PF_STATS + \
90+
NUM_FLOW_PRIORITY_STATS_RX)
91+
8792
struct mlx4_en_flow_stats_tx {
8893
u64 tx_pause;
8994
u64 tx_pause_duration;
@@ -93,6 +98,13 @@ struct mlx4_en_flow_stats_tx {
9398
MLX4_NUM_PRIORITIES)
9499
};
95100

101+
#define FLOW_PRIORITY_STATS_IDX_TX_FRAMES (NUM_MAIN_STATS + \
102+
NUM_PORT_STATS + \
103+
NUM_PF_STATS + \
104+
NUM_FLOW_PRIORITY_STATS_RX + \
105+
NUM_FLOW_STATS_RX + \
106+
NUM_FLOW_PRIORITY_STATS_TX)
107+
96108
#define NUM_FLOW_STATS (NUM_FLOW_STATS_RX + NUM_FLOW_STATS_TX + \
97109
NUM_FLOW_PRIORITY_STATS_TX + \
98110
NUM_FLOW_PRIORITY_STATS_RX)

drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1341,6 +1341,14 @@ static int mlx5e_set_tunable(struct net_device *dev,
13411341
return err;
13421342
}
13431343

1344+
static void mlx5e_get_pause_stats(struct net_device *netdev,
1345+
struct ethtool_pause_stats *pause_stats)
1346+
{
1347+
struct mlx5e_priv *priv = netdev_priv(netdev);
1348+
1349+
mlx5e_stats_pause_get(priv, pause_stats);
1350+
}
1351+
13441352
void mlx5e_ethtool_get_pauseparam(struct mlx5e_priv *priv,
13451353
struct ethtool_pauseparam *pauseparam)
13461354
{
@@ -2033,6 +2041,7 @@ const struct ethtool_ops mlx5e_ethtool_ops = {
20332041
.set_rxnfc = mlx5e_set_rxnfc,
20342042
.get_tunable = mlx5e_get_tunable,
20352043
.set_tunable = mlx5e_set_tunable,
2044+
.get_pause_stats = mlx5e_get_pause_stats,
20362045
.get_pauseparam = mlx5e_get_pauseparam,
20372046
.set_pauseparam = mlx5e_set_pauseparam,
20382047
.get_ts_info = mlx5e_get_ts_info,

drivers/net/ethernet/mellanox/mlx5/core/en_rep.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,14 @@ static u32 mlx5e_rep_get_rxfh_indir_size(struct net_device *netdev)
288288
return mlx5e_ethtool_get_rxfh_indir_size(priv);
289289
}
290290

291+
static void mlx5e_uplink_rep_get_pause_stats(struct net_device *netdev,
292+
struct ethtool_pause_stats *stats)
293+
{
294+
struct mlx5e_priv *priv = netdev_priv(netdev);
295+
296+
mlx5e_stats_pause_get(priv, stats);
297+
}
298+
291299
static void mlx5e_uplink_rep_get_pauseparam(struct net_device *netdev,
292300
struct ethtool_pauseparam *pauseparam)
293301
{
@@ -362,6 +370,7 @@ static const struct ethtool_ops mlx5e_uplink_rep_ethtool_ops = {
362370
.set_rxfh = mlx5e_set_rxfh,
363371
.get_rxnfc = mlx5e_get_rxnfc,
364372
.set_rxnfc = mlx5e_set_rxnfc,
373+
.get_pause_stats = mlx5e_uplink_rep_get_pause_stats,
365374
.get_pauseparam = mlx5e_uplink_rep_get_pauseparam,
366375
.set_pauseparam = mlx5e_uplink_rep_set_pauseparam,
367376
};

drivers/net/ethernet/mellanox/mlx5/core/en_stats.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,35 @@ static MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(802_3)
677677
mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0);
678678
}
679679

680+
#define MLX5E_READ_CTR64_BE_F(ptr, c) \
681+
be64_to_cpu(*(__be64 *)((char *)ptr + \
682+
MLX5_BYTE_OFF(ppcnt_reg, \
683+
counter_set.eth_802_3_cntrs_grp_data_layout.c##_high)))
684+
685+
void mlx5e_stats_pause_get(struct mlx5e_priv *priv,
686+
struct ethtool_pause_stats *pause_stats)
687+
{
688+
u32 ppcnt_ieee_802_3[MLX5_ST_SZ_DW(ppcnt_reg)];
689+
struct mlx5_core_dev *mdev = priv->mdev;
690+
u32 in[MLX5_ST_SZ_DW(ppcnt_reg)] = {};
691+
int sz = MLX5_ST_SZ_BYTES(ppcnt_reg);
692+
693+
if (!MLX5_BASIC_PPCNT_SUPPORTED(mdev))
694+
return;
695+
696+
MLX5_SET(ppcnt_reg, in, local_port, 1);
697+
MLX5_SET(ppcnt_reg, in, grp, MLX5_IEEE_802_3_COUNTERS_GROUP);
698+
mlx5_core_access_reg(mdev, in, sz, ppcnt_ieee_802_3,
699+
sz, MLX5_REG_PPCNT, 0, 0);
700+
701+
pause_stats->tx_pause_frames =
702+
MLX5E_READ_CTR64_BE_F(ppcnt_ieee_802_3,
703+
a_pause_mac_ctrl_frames_transmitted);
704+
pause_stats->rx_pause_frames =
705+
MLX5E_READ_CTR64_BE_F(ppcnt_ieee_802_3,
706+
a_pause_mac_ctrl_frames_received);
707+
}
708+
680709
#define PPORT_2863_OFF(c) \
681710
MLX5_BYTE_OFF(ppcnt_reg, \
682711
counter_set.eth_2863_cntrs_grp_data_layout.c##_high)

drivers/net/ethernet/mellanox/mlx5/core/en_stats.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ void mlx5e_stats_update(struct mlx5e_priv *priv);
104104
void mlx5e_stats_fill(struct mlx5e_priv *priv, u64 *data, int idx);
105105
void mlx5e_stats_fill_strings(struct mlx5e_priv *priv, u8 *data);
106106

107+
void mlx5e_stats_pause_get(struct mlx5e_priv *priv,
108+
struct ethtool_pause_stats *pause_stats);
109+
107110
/* Concrete NIC Stats */
108111

109112
struct mlx5e_sw_stats {

0 commit comments

Comments
 (0)