Commit 982c3e29 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'mlxsw-L3-HW-stats-improvements'

Ido Schimmel says:

====================
mlxsw: L3 HW stats improvements

While testing L3 HW stats [1] on top of mlxsw, two issues were found:

1. Stats cannot be enabled for more than 205 netdevs. This was fixed in
commit 4b7a632a ("mlxsw: spectrum_cnt: Reorder counter pools").

2. ARP packets are counted as errors. Patch #1 takes care of that. See
the commit message for details.

The goal of the majority of the rest of the patches is to add selftests
that would have discovered that only about 205 netdevs can have L3 HW
stats supported, despite the HW supporting much more. The obvious place
to plug this in is the scale test framework.

The scale tests are currently testing two things: that some number of
instances of a given resource can actually be created; and that when an
attempt is made to create more than the supported amount, the failures
are noted and handled gracefully.

However the ability to allocate the resource does not mean that the
resource actually works when passing traffic. For that, make it possible
for a given scale to also test traffic.

To that end, this patchset adds traffic tests. The goal of these is to
run traffic and observe whether a sample of the allocated resource
instances actually perform their task. Traffic tests are only run on the
positive leg of the scale test (no point trying to pass traffic when the
expected outcome is that the resource will not be allocated). They are
opt-in, if a given test does not expose it, it is not run.

The patchset proceeds as follows:

- Patches #2 and #3 add to "devlink resource" support for number of
  allocated RIFs, and the capacity. This is necessary, because when
  evaluating how many L3 HW stats instances it should be possible to
  allocate, the limiting resource on Spectrum-2 and above currently is
  not the counters themselves, but actually the RIFs.

- Patch #6 adds support for invocation of a traffic test, if a given scale
  tests exposes it.

- Patch #7 adds support for skipping a given scale test. Because on
  Spectrum-2 and above, the limiting factor to L3 HW stats instances is
  actually the number of RIFs, there is no point in running the failing leg
  of a scale tests, because it would test exhaustion of RIFs, not of RIF
  counters.

- With patch #8, the scale tests drivers pass the target number to the
  cleanup function of a scale test.

- In patch #9, add a traffic test to the tc_flower selftests. This makes
  sure that the flow counters installed with the ACLs actually do count as
  they are supposed to.

- In patch #10, add a new scale selftest for RIF counter scale, including a
  traffic test.

- In patch #11, the scale target for the tc_flower selftest is
  dynamically set instead of being hard coded.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ca0a53dcec9495d1dc5bbc369c810c520d728373


====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents e42134b5 ed62af45
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -3580,6 +3580,25 @@ mlxsw_sp_resources_rif_mac_profile_register(struct mlxsw_core *mlxsw_core)
					 &size_params);
}

static int mlxsw_sp_resources_rifs_register(struct mlxsw_core *mlxsw_core)
{
	struct devlink *devlink = priv_to_devlink(mlxsw_core);
	struct devlink_resource_size_params size_params;
	u64 max_rifs;

	if (!MLXSW_CORE_RES_VALID(mlxsw_core, MAX_RIFS))
		return -EIO;

	max_rifs = MLXSW_CORE_RES_GET(mlxsw_core, MAX_RIFS);
	devlink_resource_size_params_init(&size_params, max_rifs, max_rifs,
					  1, DEVLINK_RESOURCE_UNIT_ENTRY);

	return devlink_resource_register(devlink, "rifs", max_rifs,
					 MLXSW_SP_RESOURCE_RIFS,
					 DEVLINK_RESOURCE_ID_PARENT_TOP,
					 &size_params);
}

static int mlxsw_sp1_resources_register(struct mlxsw_core *mlxsw_core)
{
	int err;
@@ -3604,8 +3623,13 @@ static int mlxsw_sp1_resources_register(struct mlxsw_core *mlxsw_core)
	if (err)
		goto err_resources_rif_mac_profile_register;

	err = mlxsw_sp_resources_rifs_register(mlxsw_core);
	if (err)
		goto err_resources_rifs_register;

	return 0;

err_resources_rifs_register:
err_resources_rif_mac_profile_register:
err_policer_resources_register:
err_resources_counter_register:
@@ -3638,8 +3662,13 @@ static int mlxsw_sp2_resources_register(struct mlxsw_core *mlxsw_core)
	if (err)
		goto err_resources_rif_mac_profile_register;

	err = mlxsw_sp_resources_rifs_register(mlxsw_core);
	if (err)
		goto err_resources_rifs_register;

	return 0;

err_resources_rifs_register:
err_resources_rif_mac_profile_register:
err_policer_resources_register:
err_resources_counter_register:
+1 −0
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ enum mlxsw_sp_resource_id {
	MLXSW_SP_RESOURCE_GLOBAL_POLICERS,
	MLXSW_SP_RESOURCE_SINGLE_RATE_POLICERS,
	MLXSW_SP_RESOURCE_RIF_MAC_PROFILES,
	MLXSW_SP_RESOURCE_RIFS,
};

struct mlxsw_sp_port;
+18 −0
Original line number Diff line number Diff line
@@ -8134,6 +8134,7 @@ mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp,
		mlxsw_sp_rif_counters_alloc(rif);
	}

	atomic_inc(&mlxsw_sp->router->rifs_count);
	return rif;

err_stats_enable:
@@ -8163,6 +8164,7 @@ static void mlxsw_sp_rif_destroy(struct mlxsw_sp_rif *rif)
	struct mlxsw_sp_vr *vr;
	int i;

	atomic_dec(&mlxsw_sp->router->rifs_count);
	mlxsw_sp_router_rif_gone_sync(mlxsw_sp, rif);
	vr = &mlxsw_sp->router->vrs[rif->vr_id];

@@ -8321,6 +8323,13 @@ static u64 mlxsw_sp_rif_mac_profiles_occ_get(void *priv)
	return atomic_read(&mlxsw_sp->router->rif_mac_profiles_count);
}

static u64 mlxsw_sp_rifs_occ_get(void *priv)
{
	const struct mlxsw_sp *mlxsw_sp = priv;

	return atomic_read(&mlxsw_sp->router->rifs_count);
}

static struct mlxsw_sp_rif_mac_profile *
mlxsw_sp_rif_mac_profile_create(struct mlxsw_sp *mlxsw_sp, const char *mac,
				struct netlink_ext_ack *extack)
@@ -9652,6 +9661,7 @@ mlxsw_sp_ul_rif_create(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_vr *vr,
	if (err)
		goto ul_rif_op_err;

	atomic_inc(&mlxsw_sp->router->rifs_count);
	return ul_rif;

ul_rif_op_err:
@@ -9664,6 +9674,7 @@ static void mlxsw_sp_ul_rif_destroy(struct mlxsw_sp_rif *ul_rif)
{
	struct mlxsw_sp *mlxsw_sp = ul_rif->mlxsw_sp;

	atomic_dec(&mlxsw_sp->router->rifs_count);
	mlxsw_sp_rif_ipip_lb_ul_rif_op(ul_rif, false);
	mlxsw_sp->router->rifs[ul_rif->rif_index] = NULL;
	kfree(ul_rif);
@@ -9819,10 +9830,15 @@ static int mlxsw_sp_rifs_init(struct mlxsw_sp *mlxsw_sp)

	idr_init(&mlxsw_sp->router->rif_mac_profiles_idr);
	atomic_set(&mlxsw_sp->router->rif_mac_profiles_count, 0);
	atomic_set(&mlxsw_sp->router->rifs_count, 0);
	devlink_resource_occ_get_register(devlink,
					  MLXSW_SP_RESOURCE_RIF_MAC_PROFILES,
					  mlxsw_sp_rif_mac_profiles_occ_get,
					  mlxsw_sp);
	devlink_resource_occ_get_register(devlink,
					  MLXSW_SP_RESOURCE_RIFS,
					  mlxsw_sp_rifs_occ_get,
					  mlxsw_sp);

	return 0;
}
@@ -9832,9 +9848,11 @@ static void mlxsw_sp_rifs_fini(struct mlxsw_sp *mlxsw_sp)
	struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
	int i;

	WARN_ON_ONCE(atomic_read(&mlxsw_sp->router->rifs_count));
	for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++)
		WARN_ON_ONCE(mlxsw_sp->router->rifs[i]);

	devlink_resource_occ_get_unregister(devlink, MLXSW_SP_RESOURCE_RIFS);
	devlink_resource_occ_get_unregister(devlink,
					    MLXSW_SP_RESOURCE_RIF_MAC_PROFILES);
	WARN_ON(!idr_is_empty(&mlxsw_sp->router->rif_mac_profiles_idr));
+1 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ struct mlxsw_sp_router {
	struct mlxsw_sp_rif **rifs;
	struct idr rif_mac_profiles_idr;
	atomic_t rif_mac_profiles_count;
	atomic_t rifs_count;
	u8 max_rif_mac_profile;
	struct mlxsw_sp_vr *vrs;
	struct rhashtable neigh_ht;
+4 −4
Original line number Diff line number Diff line
@@ -953,16 +953,16 @@ static const struct mlxsw_sp_trap_item mlxsw_sp_trap_items_arr[] = {
		.trap = MLXSW_SP_TRAP_CONTROL(ARP_REQUEST, NEIGH_DISCOVERY,
					      MIRROR),
		.listeners_arr = {
			MLXSW_SP_RXL_MARK(ARPBC, NEIGH_DISCOVERY, MIRROR_TO_CPU,
					  false),
			MLXSW_SP_RXL_MARK(ROUTER_ARPBC, NEIGH_DISCOVERY,
					  TRAP_TO_CPU, false),
		},
	},
	{
		.trap = MLXSW_SP_TRAP_CONTROL(ARP_RESPONSE, NEIGH_DISCOVERY,
					      MIRROR),
		.listeners_arr = {
			MLXSW_SP_RXL_MARK(ARPUC, NEIGH_DISCOVERY, MIRROR_TO_CPU,
					  false),
			MLXSW_SP_RXL_MARK(ROUTER_ARPUC, NEIGH_DISCOVERY,
					  TRAP_TO_CPU, false),
		},
	},
	{
Loading