Commit 9bbc8be2 authored by David S. Miller's avatar David S. Miller
Browse files

Merge tag 'mlx5-updates-2020-01-22' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux



Saeed Mahameed says:

====================
mlx5-updates-2020-01-22

This series provides updates to mlx5 driver.
1) Misc small cleanups
2) Some SW steering updates including header copy support
3) Full ethtool statistics support for E-Switch uplink representor
Some refactoring was required to share the bare-metal NIC ethtool
stats with the Uplink representor. On Top of this Vlad converts the
ethtool stats support in E-Swtich vports representors to use the mlx5e
"stats groups" infrastructure and then applied all applicable stats
to the uplink representor netdev.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 790e0114 7c453526
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -892,6 +892,8 @@ struct mlx5e_profile {
	int	(*update_rx)(struct mlx5e_priv *priv);
	void	(*update_stats)(struct mlx5e_priv *priv);
	void	(*update_carrier)(struct mlx5e_priv *priv);
	unsigned int (*stats_grps_num)(struct mlx5e_priv *priv);
	mlx5e_stats_grp_t *stats_grps;
	struct {
		mlx5e_fp_handle_rx_cqe handle_rx_cqe;
		mlx5e_fp_handle_rx_cqe handle_rx_cqe_mpwqe;
@@ -964,7 +966,6 @@ struct sk_buff *
mlx5e_skb_from_cqe_nonlinear(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe,
			     struct mlx5e_wqe_frag_info *wi, u32 cqe_bcnt);

void mlx5e_update_stats(struct mlx5e_priv *priv);
void mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats);
void mlx5e_fold_sw_stats64(struct mlx5e_priv *priv, struct rtnl_link_stats64 *s);

+5 −18
Original line number Diff line number Diff line
@@ -218,13 +218,9 @@ static const struct pflag_desc mlx5e_priv_flags[MLX5E_NUM_PFLAGS];

int mlx5e_ethtool_get_sset_count(struct mlx5e_priv *priv, int sset)
{
	int i, num_stats = 0;

	switch (sset) {
	case ETH_SS_STATS:
		for (i = 0; i < mlx5e_num_stats_grps; i++)
			num_stats += mlx5e_stats_grps[i].get_num_stats(priv);
		return num_stats;
		return mlx5e_stats_total_num(priv);
	case ETH_SS_PRIV_FLAGS:
		return MLX5E_NUM_PFLAGS;
	case ETH_SS_TEST:
@@ -242,14 +238,6 @@ static int mlx5e_get_sset_count(struct net_device *dev, int sset)
	return mlx5e_ethtool_get_sset_count(priv, sset);
}

static void mlx5e_fill_stats_strings(struct mlx5e_priv *priv, u8 *data)
{
	int i, idx = 0;

	for (i = 0; i < mlx5e_num_stats_grps; i++)
		idx = mlx5e_stats_grps[i].fill_strings(priv, data, idx);
}

void mlx5e_ethtool_get_strings(struct mlx5e_priv *priv, u32 stringset, u8 *data)
{
	int i;
@@ -268,7 +256,7 @@ void mlx5e_ethtool_get_strings(struct mlx5e_priv *priv, u32 stringset, u8 *data)
		break;

	case ETH_SS_STATS:
		mlx5e_fill_stats_strings(priv, data);
		mlx5e_stats_fill_strings(priv, data);
		break;
	}
}
@@ -283,14 +271,13 @@ static void mlx5e_get_strings(struct net_device *dev, u32 stringset, u8 *data)
void mlx5e_ethtool_get_ethtool_stats(struct mlx5e_priv *priv,
				     struct ethtool_stats *stats, u64 *data)
{
	int i, idx = 0;
	int idx = 0;

	mutex_lock(&priv->state_lock);
	mlx5e_update_stats(priv);
	mlx5e_stats_update(priv);
	mutex_unlock(&priv->state_lock);

	for (i = 0; i < mlx5e_num_stats_grps; i++)
		idx = mlx5e_stats_grps[i].fill_stats(priv, data, idx);
	mlx5e_stats_fill(priv, data, idx);
}

static void mlx5e_get_ethtool_stats(struct net_device *dev,
+7 −12
Original line number Diff line number Diff line
@@ -159,23 +159,14 @@ static void mlx5e_update_carrier_work(struct work_struct *work)
	mutex_unlock(&priv->state_lock);
}

void mlx5e_update_stats(struct mlx5e_priv *priv)
{
	int i;

	for (i = mlx5e_num_stats_grps - 1; i >= 0; i--)
		if (mlx5e_stats_grps[i].update_stats)
			mlx5e_stats_grps[i].update_stats(priv);
}

void mlx5e_update_ndo_stats(struct mlx5e_priv *priv)
{
	int i;

	for (i = mlx5e_num_stats_grps - 1; i >= 0; i--)
		if (mlx5e_stats_grps[i].update_stats_mask &
	for (i = mlx5e_nic_stats_grps_num(priv) - 1; i >= 0; i--)
		if (mlx5e_nic_stats_grps[i]->update_stats_mask &
		    MLX5E_NDO_UPDATE_STATS)
			mlx5e_stats_grps[i].update_stats(priv);
			mlx5e_nic_stats_grps[i]->update_stats(priv);
}

static void mlx5e_update_stats_work(struct work_struct *work)
@@ -4878,6 +4869,8 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
		netdev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL |
					   NETIF_F_GSO_UDP_TUNNEL_CSUM;
		netdev->gso_partial_features = NETIF_F_GSO_UDP_TUNNEL_CSUM;
		netdev->vlan_features |= NETIF_F_GSO_UDP_TUNNEL |
					 NETIF_F_GSO_UDP_TUNNEL_CSUM;
	}

	if (mlx5e_tunnel_proto_supported(mdev, IPPROTO_GRE)) {
@@ -5195,6 +5188,8 @@ static const struct mlx5e_profile mlx5e_nic_profile = {
	.rx_handlers.handle_rx_cqe_mpwqe = mlx5e_handle_rx_cqe_mpwrq,
	.max_tc		   = MLX5E_MAX_NUM_TC,
	.rq_groups	   = MLX5E_NUM_RQ_GROUPS(XSK),
	.stats_grps	   = mlx5e_nic_stats_grps,
	.stats_grps_num	   = mlx5e_nic_stats_grps_num,
};

/* mlx5e generic netdev management API (move to en_common.c) */
+186 −91
Original line number Diff line number Diff line
@@ -117,24 +117,71 @@ static const struct counter_desc vport_rep_stats_desc[] = {
#define NUM_VPORT_REP_SW_COUNTERS ARRAY_SIZE(sw_rep_stats_desc)
#define NUM_VPORT_REP_HW_COUNTERS ARRAY_SIZE(vport_rep_stats_desc)

static void mlx5e_rep_get_strings(struct net_device *dev,
				  u32 stringset, uint8_t *data)
static MLX5E_DECLARE_STATS_GRP_OP_NUM_STATS(sw_rep)
{
	int i, j;
	return NUM_VPORT_REP_SW_COUNTERS;
}

static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(sw_rep)
{
	int i;

	switch (stringset) {
	case ETH_SS_STATS:
	for (i = 0; i < NUM_VPORT_REP_SW_COUNTERS; i++)
			strcpy(data + (i * ETH_GSTRING_LEN),
		strcpy(data + (idx++) * ETH_GSTRING_LEN,
		       sw_rep_stats_desc[i].format);
		for (j = 0; j < NUM_VPORT_REP_HW_COUNTERS; j++, i++)
			strcpy(data + (i * ETH_GSTRING_LEN),
			       vport_rep_stats_desc[j].format);
		break;
	return idx;
}

static MLX5E_DECLARE_STATS_GRP_OP_FILL_STATS(sw_rep)
{
	int i;

	for (i = 0; i < NUM_VPORT_REP_SW_COUNTERS; i++)
		data[idx++] = MLX5E_READ_CTR64_CPU(&priv->stats.sw,
						   sw_rep_stats_desc, i);
	return idx;
}

static void mlx5e_rep_update_hw_counters(struct mlx5e_priv *priv)
static MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(sw_rep)
{
	struct mlx5e_sw_stats *s = &priv->stats.sw;
	struct rtnl_link_stats64 stats64 = {};

	memset(s, 0, sizeof(*s));
	mlx5e_fold_sw_stats64(priv, &stats64);

	s->rx_packets = stats64.rx_packets;
	s->rx_bytes   = stats64.rx_bytes;
	s->tx_packets = stats64.tx_packets;
	s->tx_bytes   = stats64.tx_bytes;
	s->tx_queue_dropped = stats64.tx_dropped;
}

static MLX5E_DECLARE_STATS_GRP_OP_NUM_STATS(vport_rep)
{
	return NUM_VPORT_REP_HW_COUNTERS;
}

static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(vport_rep)
{
	int i;

	for (i = 0; i < NUM_VPORT_REP_HW_COUNTERS; i++)
		strcpy(data + (idx++) * ETH_GSTRING_LEN, vport_rep_stats_desc[i].format);
	return idx;
}

static MLX5E_DECLARE_STATS_GRP_OP_FILL_STATS(vport_rep)
{
	int i;

	for (i = 0; i < NUM_VPORT_REP_HW_COUNTERS; i++)
		data[idx++] = MLX5E_READ_CTR64_CPU(&priv->stats.vf_vport,
						   vport_rep_stats_desc, i);
	return idx;
}

static MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(vport_rep)
{
	struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
	struct mlx5e_rep_priv *rpriv = priv->ppriv;
@@ -157,64 +204,33 @@ static void mlx5e_rep_update_hw_counters(struct mlx5e_priv *priv)
	vport_stats->tx_bytes   = vf_stats.rx_bytes;
}

static void mlx5e_uplink_rep_update_hw_counters(struct mlx5e_priv *priv)
static void mlx5e_rep_get_strings(struct net_device *dev,
				  u32 stringset, uint8_t *data)
{
	struct mlx5e_pport_stats *pstats = &priv->stats.pport;
	struct rtnl_link_stats64 *vport_stats;

	mlx5e_grp_802_3_update_stats(priv);

	vport_stats = &priv->stats.vf_vport;
	struct mlx5e_priv *priv = netdev_priv(dev);

	vport_stats->rx_packets = PPORT_802_3_GET(pstats, a_frames_received_ok);
	vport_stats->rx_bytes   = PPORT_802_3_GET(pstats, a_octets_received_ok);
	vport_stats->tx_packets = PPORT_802_3_GET(pstats, a_frames_transmitted_ok);
	vport_stats->tx_bytes   = PPORT_802_3_GET(pstats, a_octets_transmitted_ok);
	switch (stringset) {
	case ETH_SS_STATS:
		mlx5e_stats_fill_strings(priv, data);
		break;
	}

static void mlx5e_rep_update_sw_counters(struct mlx5e_priv *priv)
{
	struct mlx5e_sw_stats *s = &priv->stats.sw;
	struct rtnl_link_stats64 stats64 = {};

	memset(s, 0, sizeof(*s));
	mlx5e_fold_sw_stats64(priv, &stats64);

	s->rx_packets = stats64.rx_packets;
	s->rx_bytes   = stats64.rx_bytes;
	s->tx_packets = stats64.tx_packets;
	s->tx_bytes   = stats64.tx_bytes;
	s->tx_queue_dropped = stats64.tx_dropped;
}

static void mlx5e_rep_get_ethtool_stats(struct net_device *dev,
					struct ethtool_stats *stats, u64 *data)
{
	struct mlx5e_priv *priv = netdev_priv(dev);
	int i, j;

	if (!data)
		return;

	mutex_lock(&priv->state_lock);
	mlx5e_rep_update_sw_counters(priv);
	priv->profile->update_stats(priv);
	mutex_unlock(&priv->state_lock);

	for (i = 0; i < NUM_VPORT_REP_SW_COUNTERS; i++)
		data[i] = MLX5E_READ_CTR64_CPU(&priv->stats.sw,
					       sw_rep_stats_desc, i);

	for (j = 0; j < NUM_VPORT_REP_HW_COUNTERS; j++, i++)
		data[i] = MLX5E_READ_CTR64_CPU(&priv->stats.vf_vport,
					       vport_rep_stats_desc, j);
	mlx5e_ethtool_get_ethtool_stats(priv, stats, data);
}

static int mlx5e_rep_get_sset_count(struct net_device *dev, int sset)
{
	struct mlx5e_priv *priv = netdev_priv(dev);

	switch (sset) {
	case ETH_SS_STATS:
		return NUM_VPORT_REP_SW_COUNTERS + NUM_VPORT_REP_HW_COUNTERS;
		return mlx5e_stats_total_num(priv);
	default:
		return -EOPNOTSUPP;
	}
@@ -1674,19 +1690,32 @@ static void mlx5e_cleanup_rep_rx(struct mlx5e_priv *priv)
	mlx5e_close_drop_rq(&priv->drop_rq);
}

static int mlx5e_init_rep_tx(struct mlx5e_priv *priv)
static int mlx5e_init_ul_rep_rx(struct mlx5e_priv *priv)
{
	struct mlx5e_rep_priv *rpriv = priv->ppriv;
	struct mlx5_rep_uplink_priv *uplink_priv;
	int err;
	int err = mlx5e_init_rep_rx(priv);

	err = mlx5e_create_tises(priv);
	if (err) {
		mlx5_core_warn(priv->mdev, "create tises failed, %d\n", err);
	if (err)
		return err;

	mlx5e_create_q_counters(priv);
	return 0;
}

	if (rpriv->rep->vport == MLX5_VPORT_UPLINK) {
static void mlx5e_cleanup_ul_rep_rx(struct mlx5e_priv *priv)
{
	mlx5e_destroy_q_counters(priv);
	mlx5e_cleanup_rep_rx(priv);
}

static int mlx5e_init_uplink_rep_tx(struct mlx5e_rep_priv *rpriv)
{
	struct mlx5_rep_uplink_priv *uplink_priv;
	struct net_device *netdev;
	struct mlx5e_priv *priv;
	int err;

	netdev = rpriv->netdev;
	priv = netdev_priv(netdev);
	uplink_priv = &rpriv->uplink_priv;

	mutex_init(&uplink_priv->unready_flows_lock);
@@ -1695,7 +1724,7 @@ static int mlx5e_init_rep_tx(struct mlx5e_priv *priv)
	/* init shared tc flow table */
	err = mlx5e_tc_esw_init(&uplink_priv->tc_ht);
	if (err)
			goto destroy_tises;
		return err;

	mlx5_init_port_tun_entropy(&uplink_priv->tun_entropy, priv->mdev);

@@ -1707,24 +1736,40 @@ static int mlx5e_init_rep_tx(struct mlx5e_priv *priv)
		mlx5_core_err(priv->mdev, "Failed to register netdev notifier\n");
		goto tc_esw_cleanup;
	}
	}

	return 0;

tc_esw_cleanup:
	mlx5e_tc_esw_cleanup(&uplink_priv->tc_ht);
destroy_tises:
	mlx5e_destroy_tises(priv);
	return err;
}

static void mlx5e_cleanup_rep_tx(struct mlx5e_priv *priv)
static int mlx5e_init_rep_tx(struct mlx5e_priv *priv)
{
	struct mlx5e_rep_priv *rpriv = priv->ppriv;
	int err;

	mlx5e_destroy_tises(priv);
	err = mlx5e_create_tises(priv);
	if (err) {
		mlx5_core_warn(priv->mdev, "create tises failed, %d\n", err);
		return err;
	}

	if (rpriv->rep->vport == MLX5_VPORT_UPLINK) {
		err = mlx5e_init_uplink_rep_tx(rpriv);
		if (err)
			goto destroy_tises;
	}

	return 0;

destroy_tises:
	mlx5e_destroy_tises(priv);
	return err;
}

static void mlx5e_cleanup_uplink_rep_tx(struct mlx5e_rep_priv *rpriv)
{
	/* clean indirect TC block notifications */
	unregister_netdevice_notifier(&rpriv->uplink_priv.netdevice_nb);
	mlx5e_rep_indr_clean_block_privs(rpriv);
@@ -1733,6 +1778,15 @@ static void mlx5e_cleanup_rep_tx(struct mlx5e_priv *priv)
	mlx5e_tc_esw_cleanup(&rpriv->uplink_priv.tc_ht);
	mutex_destroy(&rpriv->uplink_priv.unready_flows_lock);
}

static void mlx5e_cleanup_rep_tx(struct mlx5e_priv *priv)
{
	struct mlx5e_rep_priv *rpriv = priv->ppriv;

	mlx5e_destroy_tises(priv);

	if (rpriv->rep->vport == MLX5_VPORT_UPLINK)
		mlx5e_cleanup_uplink_rep_tx(rpriv);
}

static void mlx5e_rep_enable(struct mlx5e_priv *priv)
@@ -1812,6 +1866,43 @@ static void mlx5e_uplink_rep_disable(struct mlx5e_priv *priv)
	mlx5_lag_remove(mdev);
}

static MLX5E_DEFINE_STATS_GRP(sw_rep, 0);
static MLX5E_DEFINE_STATS_GRP(vport_rep, MLX5E_NDO_UPDATE_STATS);

/* The stats groups order is opposite to the update_stats() order calls */
static mlx5e_stats_grp_t mlx5e_rep_stats_grps[] = {
	&MLX5E_STATS_GRP(sw_rep),
	&MLX5E_STATS_GRP(vport_rep),
};

static unsigned int mlx5e_rep_stats_grps_num(struct mlx5e_priv *priv)
{
	return ARRAY_SIZE(mlx5e_rep_stats_grps);
}

/* The stats groups order is opposite to the update_stats() order calls */
static mlx5e_stats_grp_t mlx5e_ul_rep_stats_grps[] = {
	&MLX5E_STATS_GRP(sw),
	&MLX5E_STATS_GRP(qcnt),
	&MLX5E_STATS_GRP(vnic_env),
	&MLX5E_STATS_GRP(vport),
	&MLX5E_STATS_GRP(802_3),
	&MLX5E_STATS_GRP(2863),
	&MLX5E_STATS_GRP(2819),
	&MLX5E_STATS_GRP(phy),
	&MLX5E_STATS_GRP(eth_ext),
	&MLX5E_STATS_GRP(pcie),
	&MLX5E_STATS_GRP(per_prio),
	&MLX5E_STATS_GRP(pme),
	&MLX5E_STATS_GRP(channels),
	&MLX5E_STATS_GRP(per_port_buff_congest),
};

static unsigned int mlx5e_ul_rep_stats_grps_num(struct mlx5e_priv *priv)
{
	return ARRAY_SIZE(mlx5e_ul_rep_stats_grps);
}

static const struct mlx5e_profile mlx5e_rep_profile = {
	.init			= mlx5e_init_rep,
	.cleanup		= mlx5e_cleanup_rep,
@@ -1821,29 +1912,33 @@ static const struct mlx5e_profile mlx5e_rep_profile = {
	.cleanup_tx		= mlx5e_cleanup_rep_tx,
	.enable		        = mlx5e_rep_enable,
	.update_rx		= mlx5e_update_rep_rx,
	.update_stats           = mlx5e_rep_update_hw_counters,
	.update_stats           = mlx5e_update_ndo_stats,
	.rx_handlers.handle_rx_cqe       = mlx5e_handle_rx_cqe_rep,
	.rx_handlers.handle_rx_cqe_mpwqe = mlx5e_handle_rx_cqe_mpwrq,
	.max_tc			= 1,
	.rq_groups		= MLX5E_NUM_RQ_GROUPS(REGULAR),
	.stats_grps		= mlx5e_rep_stats_grps,
	.stats_grps_num		= mlx5e_rep_stats_grps_num,
};

static const struct mlx5e_profile mlx5e_uplink_rep_profile = {
	.init			= mlx5e_init_rep,
	.cleanup		= mlx5e_cleanup_rep,
	.init_rx		= mlx5e_init_rep_rx,
	.cleanup_rx		= mlx5e_cleanup_rep_rx,
	.init_rx		= mlx5e_init_ul_rep_rx,
	.cleanup_rx		= mlx5e_cleanup_ul_rep_rx,
	.init_tx		= mlx5e_init_rep_tx,
	.cleanup_tx		= mlx5e_cleanup_rep_tx,
	.enable		        = mlx5e_uplink_rep_enable,
	.disable	        = mlx5e_uplink_rep_disable,
	.update_rx		= mlx5e_update_rep_rx,
	.update_stats           = mlx5e_uplink_rep_update_hw_counters,
	.update_stats           = mlx5e_update_ndo_stats,
	.update_carrier	        = mlx5e_update_carrier,
	.rx_handlers.handle_rx_cqe       = mlx5e_handle_rx_cqe_rep,
	.rx_handlers.handle_rx_cqe_mpwqe = mlx5e_handle_rx_cqe_mpwrq,
	.max_tc			= MLX5E_MAX_NUM_TC,
	.rq_groups		= MLX5E_NUM_RQ_GROUPS(REGULAR),
	.stats_grps		= mlx5e_ul_rep_stats_grps,
	.stats_grps_num		= mlx5e_ul_rep_stats_grps_num,
};

static bool
+157 −185

File changed.

Preview size limit exceeded, changes collapsed.

Loading