Skip to content

Commit

Permalink
Merge branch 'ethtool-hw-timestamping-statistics'
Browse files Browse the repository at this point in the history
Rahul Rameshbabu says:

====================
ethtool HW timestamping statistics

The goal of this patch series is to introduce a common set of ethtool
statistics for hardware timestamping that a driver implementer can hook into.
The statistics counters added are based on what I believe are common
patterns/behaviors found across various hardware timestamping implementations
seen in the kernel tree today. The mlx5 family of devices is used
as the PoC for this patch series. Other vendors are more than welcome
to chime in on this series.

Link: https://lore.kernel.org/netdev/20240402205223.137565-1-rrameshbabu@nvidia.com/
Link: https://lore.kernel.org/netdev/20240309084440.299358-1-rrameshbabu@nvidia.com/
Link: https://lore.kernel.org/netdev/20240223192658.45893-1-rrameshbabu@nvidia.com/
Signed-off-by: Rahul Rameshbabu <rrameshbabu@nvidia.com>
====================

Link: https://lore.kernel.org/r/20240403212931.128541-1-rrameshbabu@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Jakub Kicinski committed Apr 6, 2024
2 parents 4196aee + 2e0e148 commit 571faef
Show file tree
Hide file tree
Showing 12 changed files with 209 additions and 12 deletions.
18 changes: 17 additions & 1 deletion Documentation/netlink/specs/ethtool.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ definitions:
entries: []
-
name: header-flags
enum-name:
type: flags
entries: [ compact-bitsets, omit-reply, stats ]

Expand Down Expand Up @@ -565,6 +564,18 @@ attribute-sets:
-
name: tx-lpi-timer
type: u32
-
name: ts-stat
attributes:
-
name: tx-pkts
type: uint
-
name: tx-lost
type: uint
-
name: tx-err
type: uint
-
name: tsinfo
attributes:
Expand All @@ -587,6 +598,10 @@ attribute-sets:
-
name: phc-index
type: u32
-
name: stats
type: nest
nested-attributes: ts-stat
-
name: cable-result
attributes:
Expand Down Expand Up @@ -1394,6 +1409,7 @@ operations:
- tx-types
- rx-filters
- phc-index
- stats
dump: *tsinfo-get-op
-
name: cable-test-act
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,11 @@ the software port.
in the beginning of the queue. This is a normal condition.
- Informative

* - `tx[i]_timestamps`
- Transmitted packets that were hardware timestamped at the device's DMA
layer.
- Informative

* - `tx[i]_added_vlan_packets`
- The number of packets sent where vlan tag insertion was offloaded to the
hardware.
Expand Down Expand Up @@ -702,6 +707,12 @@ the software port.
the device typically ensures not posting the CQE.
- Error

* - `ptp_cq[i]_lost_cqe`
- Number of times a CQE is expected to not be delivered on the PTP
timestamping CQE by the device due to a time delta elapsing. If such a
CQE is somehow delivered, `ptp_cq[i]_late_cqe` is incremented.
- Error

.. [#ring_global] The corresponding ring and global counters do not share the
same name (i.e. do not follow the common naming scheme).
Expand Down
9 changes: 9 additions & 0 deletions Documentation/networking/ethtool-netlink.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1237,12 +1237,21 @@ Kernel response contents:
``ETHTOOL_A_TSINFO_TX_TYPES`` bitset supported Tx types
``ETHTOOL_A_TSINFO_RX_FILTERS`` bitset supported Rx filters
``ETHTOOL_A_TSINFO_PHC_INDEX`` u32 PTP hw clock index
``ETHTOOL_A_TSINFO_STATS`` nested HW timestamping statistics
===================================== ====== ==========================

``ETHTOOL_A_TSINFO_PHC_INDEX`` is absent if there is no associated PHC (there
is no special value for this case). The bitset attributes are omitted if they
would be empty (no bit set).

Additional hardware timestamping statistics response contents:

===================================== ====== ===================================
``ETHTOOL_A_TS_STAT_TX_PKTS`` u64 Packets with Tx HW timestamps
``ETHTOOL_A_TS_STAT_TX_LOST`` u64 Tx HW timestamp not arrived count
``ETHTOOL_A_TS_STAT_TX_ERR`` u64 HW error request Tx timestamp count
===================================== ====== ===================================

CABLE_TEST
==========

Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ static void mlx5e_ptpsq_mark_ts_cqes_undelivered(struct mlx5e_ptpsq *ptpsq,
WARN_ON_ONCE(!pos->inuse);
pos->inuse = false;
list_del(&pos->entry);
ptpsq->cq_stats->lost_cqe++;
}
spin_unlock_bh(&cqe_list->tracker_list_lock);
}
Expand Down
9 changes: 9 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -2387,6 +2387,14 @@ static void mlx5e_get_rmon_stats(struct net_device *netdev,
mlx5e_stats_rmon_get(priv, rmon_stats, ranges);
}

static void mlx5e_get_ts_stats(struct net_device *netdev,
struct ethtool_ts_stats *ts_stats)
{
struct mlx5e_priv *priv = netdev_priv(netdev);

mlx5e_stats_ts_get(priv, ts_stats);
}

const struct ethtool_ops mlx5e_ethtool_ops = {
.cap_rss_ctx_supported = true,
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
Expand Down Expand Up @@ -2436,5 +2444,6 @@ const struct ethtool_ops mlx5e_ethtool_ops = {
.get_eth_mac_stats = mlx5e_get_eth_mac_stats,
.get_eth_ctrl_stats = mlx5e_get_eth_ctrl_stats,
.get_rmon_stats = mlx5e_get_rmon_stats,
.get_ts_stats = mlx5e_get_ts_stats,
.get_link_ext_stats = mlx5e_get_link_ext_stats
};
48 changes: 48 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
Original file line number Diff line number Diff line change
Expand Up @@ -1172,6 +1172,51 @@ void mlx5e_stats_rmon_get(struct mlx5e_priv *priv,
*ranges = mlx5e_rmon_ranges;
}

void mlx5e_stats_ts_get(struct mlx5e_priv *priv,
struct ethtool_ts_stats *ts_stats)
{
int i, j;

mutex_lock(&priv->state_lock);

if (priv->tx_ptp_opened) {
struct mlx5e_ptp *ptp = priv->channels.ptp;

ts_stats->pkts = 0;
ts_stats->err = 0;
ts_stats->lost = 0;

/* Aggregate stats across all TCs */
for (i = 0; i < ptp->num_tc; i++) {
struct mlx5e_ptp_cq_stats *stats =
ptp->ptpsq[i].cq_stats;

ts_stats->pkts += stats->cqe;
ts_stats->err += stats->abort + stats->err_cqe +
stats->late_cqe;
ts_stats->lost += stats->lost_cqe;
}
} else {
/* DMA layer will always successfully timestamp packets. Other
* counters do not make sense for this layer.
*/
ts_stats->pkts = 0;

/* Aggregate stats across all SQs */
for (j = 0; j < priv->channels.num; j++) {
struct mlx5e_channel *c = priv->channels.c[j];

for (i = 0; i < c->num_tc; i++) {
struct mlx5e_sq_stats *stats = c->sq[i].stats;

ts_stats->pkts += stats->timestamps;
}
}
}

mutex_unlock(&priv->state_lock);
}

#define PPORT_PHY_STATISTICAL_OFF(c) \
MLX5_BYTE_OFF(ppcnt_reg, \
counter_set.phys_layer_statistical_cntrs.c##_high)
Expand Down Expand Up @@ -2066,6 +2111,7 @@ static const struct counter_desc sq_stats_desc[] = {
{ MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, csum_partial_inner) },
{ MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, added_vlan_packets) },
{ MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, nop) },
{ MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, timestamps) },
{ MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, mpwqe_blks) },
{ MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, mpwqe_pkts) },
#ifdef CONFIG_MLX5_EN_TLS
Expand Down Expand Up @@ -2178,6 +2224,7 @@ static const struct counter_desc ptp_cq_stats_desc[] = {
{ MLX5E_DECLARE_PTP_CQ_STAT(struct mlx5e_ptp_cq_stats, abort) },
{ MLX5E_DECLARE_PTP_CQ_STAT(struct mlx5e_ptp_cq_stats, abort_abs_diff_ns) },
{ MLX5E_DECLARE_PTP_CQ_STAT(struct mlx5e_ptp_cq_stats, late_cqe) },
{ MLX5E_DECLARE_PTP_CQ_STAT(struct mlx5e_ptp_cq_stats, lost_cqe) },
};

static const struct counter_desc ptp_rq_stats_desc[] = {
Expand Down Expand Up @@ -2217,6 +2264,7 @@ static const struct counter_desc qos_sq_stats_desc[] = {
{ MLX5E_DECLARE_QOS_TX_STAT(struct mlx5e_sq_stats, csum_partial_inner) },
{ MLX5E_DECLARE_QOS_TX_STAT(struct mlx5e_sq_stats, added_vlan_packets) },
{ MLX5E_DECLARE_QOS_TX_STAT(struct mlx5e_sq_stats, nop) },
{ MLX5E_DECLARE_QOS_TX_STAT(struct mlx5e_sq_stats, timestamps) },
{ MLX5E_DECLARE_QOS_TX_STAT(struct mlx5e_sq_stats, mpwqe_blks) },
{ MLX5E_DECLARE_QOS_TX_STAT(struct mlx5e_sq_stats, mpwqe_pkts) },
#ifdef CONFIG_MLX5_EN_TLS
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en_stats.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ void mlx5e_stats_eth_ctrl_get(struct mlx5e_priv *priv,
void mlx5e_stats_rmon_get(struct mlx5e_priv *priv,
struct ethtool_rmon_stats *rmon,
const struct ethtool_rmon_hist_range **ranges);
void mlx5e_stats_ts_get(struct mlx5e_priv *priv,
struct ethtool_ts_stats *ts_stats);
void mlx5e_get_link_ext_stats(struct net_device *dev,
struct ethtool_link_ext_stats *stats);

Expand Down Expand Up @@ -431,6 +433,7 @@ struct mlx5e_sq_stats {
u64 stopped;
u64 dropped;
u64 recover;
u64 timestamps;
/* dirtied @completion */
u64 cqes ____cacheline_aligned_in_smp;
u64 wake;
Expand Down Expand Up @@ -463,6 +466,7 @@ struct mlx5e_ptp_cq_stats {
u64 abort;
u64 abort_abs_diff_ns;
u64 late_cqe;
u64 lost_cqe;
};

struct mlx5e_rep_stats {
Expand Down
6 changes: 4 additions & 2 deletions drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -750,11 +750,13 @@ static void mlx5e_consume_skb(struct mlx5e_txqsq *sq, struct sk_buff *skb,
u64 ts = get_cqe_ts(cqe);

hwts.hwtstamp = mlx5e_cqe_ts_to_ns(sq->ptp_cyc2time, sq->clock, ts);
if (sq->ptpsq)
if (sq->ptpsq) {
mlx5e_skb_cb_hwtstamp_handler(skb, MLX5E_SKB_CB_CQE_HWTSTAMP,
hwts.hwtstamp, sq->ptpsq->cq_stats);
else
} else {
skb_tstamp_tx(skb, &hwts);
sq->stats->timestamps++;
}
}

napi_consume_skb(skb, napi_budget);
Expand Down
27 changes: 26 additions & 1 deletion include/linux/ethtool.h
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,26 @@ struct ethtool_rmon_stats {
);
};

/**
* struct ethtool_ts_stats - HW timestamping statistics
* @pkts: Number of packets successfully timestamped by the hardware.
* @lost: Number of hardware timestamping requests where the timestamping
* information from the hardware never arrived for submission with
* the skb.
* @err: Number of arbitrary timestamp generation error events that the
* hardware encountered, exclusive of @lost statistics. Cases such
* as resource exhaustion, unavailability, firmware errors, and
* detected illogical timestamp values not submitted with the skb
* are inclusive to this counter.
*/
struct ethtool_ts_stats {
struct_group(tx_stats,
u64 pkts;
u64 lost;
u64 err;
);
};

#define ETH_MODULE_EEPROM_PAGE_LEN 128
#define ETH_MODULE_MAX_I2C_ADDRESS 0x7f

Expand Down Expand Up @@ -755,7 +775,10 @@ struct ethtool_rxfh_param {
* @get_ts_info: Get the time stamping and PTP hardware clock capabilities.
* It may be called with RCU, or rtnl or reference on the device.
* Drivers supporting transmit time stamps in software should set this to
* ethtool_op_get_ts_info().
* ethtool_op_get_ts_info(). Drivers must not zero statistics which they
* don't report. The stats structure is initialized to ETHTOOL_STAT_NOT_SET
* indicating driver does not report statistics.
* @get_ts_stats: Query the device hardware timestamping statistics.
* @get_module_info: Get the size and type of the eeprom contained within
* a plug-in module.
* @get_module_eeprom: Get the eeprom information from the plug-in module
Expand Down Expand Up @@ -898,6 +921,8 @@ struct ethtool_ops {
struct ethtool_dump *, void *);
int (*set_dump)(struct net_device *, struct ethtool_dump *);
int (*get_ts_info)(struct net_device *, struct ethtool_ts_info *);
void (*get_ts_stats)(struct net_device *dev,
struct ethtool_ts_stats *ts_stats);
int (*get_module_info)(struct net_device *,
struct ethtool_modinfo *);
int (*get_module_eeprom)(struct net_device *,
Expand Down
25 changes: 19 additions & 6 deletions include/uapi/linux/ethtool_netlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,11 @@ enum {

/* request header */

/* use compact bitsets in reply */
#define ETHTOOL_FLAG_COMPACT_BITSETS (1 << 0)
/* provide optional reply for SET or ACT requests */
#define ETHTOOL_FLAG_OMIT_REPLY (1 << 1)
/* request statistics, if supported by the driver */
#define ETHTOOL_FLAG_STATS (1 << 2)
enum ethtool_header_flags {
ETHTOOL_FLAG_COMPACT_BITSETS = 1 << 0, /* use compact bitsets in reply */
ETHTOOL_FLAG_OMIT_REPLY = 1 << 1, /* provide optional reply for SET or ACT requests */
ETHTOOL_FLAG_STATS = 1 << 2, /* request statistics, if supported by the driver */
};

#define ETHTOOL_FLAG_ALL (ETHTOOL_FLAG_COMPACT_BITSETS | \
ETHTOOL_FLAG_OMIT_REPLY | \
Expand Down Expand Up @@ -478,12 +477,26 @@ enum {
ETHTOOL_A_TSINFO_TX_TYPES, /* bitset */
ETHTOOL_A_TSINFO_RX_FILTERS, /* bitset */
ETHTOOL_A_TSINFO_PHC_INDEX, /* u32 */
ETHTOOL_A_TSINFO_STATS, /* nest - _A_TSINFO_STAT */

/* add new constants above here */
__ETHTOOL_A_TSINFO_CNT,
ETHTOOL_A_TSINFO_MAX = (__ETHTOOL_A_TSINFO_CNT - 1)
};

enum {
ETHTOOL_A_TS_STAT_UNSPEC,

ETHTOOL_A_TS_STAT_TX_PKTS, /* u64 */
ETHTOOL_A_TS_STAT_TX_LOST, /* u64 */
ETHTOOL_A_TS_STAT_TX_ERR, /* u64 */

/* add new constants above here */
__ETHTOOL_A_TS_STAT_CNT,
ETHTOOL_A_TS_STAT_MAX = (__ETHTOOL_A_TS_STAT_CNT - 1)

};

/* PHC VCLOCKS */

enum {
Expand Down
Loading

0 comments on commit 571faef

Please sign in to comment.