diff mbox series

[v2,net-next,10/26] mlx5: provide generic XDP stats callbacks

Message ID 20211123163955.154512-11-alexandr.lobakin@intel.com (mailing list archive)
State Not Applicable
Headers show
Series net: introduce and use generic XDP stats | expand

Commit Message

Alexander Lobakin Nov. 23, 2021, 4:39 p.m. UTC
mlx5 driver has a bunch of per-channel stats for XDP. 7 and 5 of
them can be exported through generic XDP stats infra for XDP and XSK
correspondingly.
Add necessary calbacks for that. Note that the driver doesn't expose
XSK stats if XSK setup has never been requested.

Signed-off-by: Alexander Lobakin <alexandr.lobakin@intel.com>
Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
---
 drivers/net/ethernet/mellanox/mlx5/core/en.h  |  5 ++
 .../net/ethernet/mellanox/mlx5/core/en_main.c |  2 +
 .../ethernet/mellanox/mlx5/core/en_stats.c    | 69 +++++++++++++++++++
 3 files changed, 76 insertions(+)

--
2.33.1
diff mbox series

Patch

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index 48b12ee44b8d..cc8cf3ff7d49 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -1212,4 +1212,9 @@  int mlx5e_set_vf_rate(struct net_device *dev, int vf, int min_tx_rate, int max_t
 int mlx5e_get_vf_config(struct net_device *dev, int vf, struct ifla_vf_info *ivi);
 int mlx5e_get_vf_stats(struct net_device *dev, int vf, struct ifla_vf_stats *vf_stats);
 #endif
+
+int mlx5e_get_xdp_stats_nch(const struct net_device *dev, u32 attr_id);
+int mlx5e_get_xdp_stats(const struct net_device *dev, u32 attr_id,
+			void *attr_data);
+
 #endif /* __MLX5_EN_H__ */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 65571593ec5c..d5b3abf09c82 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -4532,6 +4532,8 @@  const struct net_device_ops mlx5e_netdev_ops = {
 	.ndo_setup_tc            = mlx5e_setup_tc,
 	.ndo_select_queue        = mlx5e_select_queue,
 	.ndo_get_stats64         = mlx5e_get_stats,
+	.ndo_get_xdp_stats_nch   = mlx5e_get_xdp_stats_nch,
+	.ndo_get_xdp_stats       = mlx5e_get_xdp_stats,
 	.ndo_set_rx_mode         = mlx5e_set_rx_mode,
 	.ndo_set_mac_address     = mlx5e_set_mac,
 	.ndo_vlan_rx_add_vid     = mlx5e_vlan_rx_add_vid,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
index 3631dafb4ea2..834457e3f19a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
@@ -2292,3 +2292,72 @@  unsigned int mlx5e_nic_stats_grps_num(struct mlx5e_priv *priv)
 {
 	return ARRAY_SIZE(mlx5e_nic_stats_grps);
 }
+
+int mlx5e_get_xdp_stats_nch(const struct net_device *dev, u32 attr_id)
+{
+	const struct mlx5e_priv *priv = netdev_priv(dev);
+
+	switch (attr_id) {
+	case IFLA_XDP_XSTATS_TYPE_XDP:
+		return priv->max_nch;
+	case IFLA_XDP_XSTATS_TYPE_XSK:
+		return priv->xsk.ever_used ? priv->max_nch : -ENODATA;
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+int mlx5e_get_xdp_stats(const struct net_device *dev, u32 attr_id,
+			void *attr_data)
+{
+	const struct mlx5e_priv *priv = netdev_priv(dev);
+	struct ifla_xdp_stats *xdp_stats = attr_data;
+	u32 i;
+
+	switch (attr_id) {
+	case IFLA_XDP_XSTATS_TYPE_XDP:
+		break;
+	case IFLA_XDP_XSTATS_TYPE_XSK:
+		if (!priv->xsk.ever_used)
+			return -ENODATA;
+
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	for (i = 0; i < priv->max_nch; i++) {
+		const struct mlx5e_channel_stats *cs = priv->channel_stats + i;
+
+		switch (attr_id) {
+		case IFLA_XDP_XSTATS_TYPE_XDP:
+			/* mlx5e_rq_stats rq */
+			xdp_stats->errors = cs->rq.xdp_errors;
+			xdp_stats->drop = cs->rq.xdp_drop;
+			xdp_stats->redirect = cs->rq.xdp_redirect;
+			/* mlx5e_xdpsq_stats rq_xdpsq */
+			xdp_stats->tx = cs->rq_xdpsq.xmit;
+			xdp_stats->tx_errors = cs->rq_xdpsq.err +
+					       cs->rq_xdpsq.full;
+			/* mlx5e_xdpsq_stats xdpsq */
+			xdp_stats->xmit_packets = cs->xdpsq.xmit;
+			xdp_stats->xmit_errors = cs->xdpsq.err;
+			xdp_stats->xmit_full = cs->xdpsq.full;
+			break;
+		case IFLA_XDP_XSTATS_TYPE_XSK:
+			/* mlx5e_rq_stats xskrq */
+			xdp_stats->errors = cs->xskrq.xdp_errors;
+			xdp_stats->drop = cs->xskrq.xdp_drop;
+			xdp_stats->redirect = cs->xskrq.xdp_redirect;
+			/* mlx5e_xdpsq_stats xsksq */
+			xdp_stats->xmit_packets = cs->xsksq.xmit;
+			xdp_stats->xmit_errors = cs->xsksq.err;
+			xdp_stats->xmit_full = cs->xsksq.full;
+			break;
+		}
+
+		xdp_stats++;
+	}
+
+	return 0;
+}