Commit bc9291de authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'mlxsw-miscellaneous-fixes'

Petr Machata says:

====================
mlxsw: Miscellaneous fixes

This patchset is a bric-a-brac of fixes for bugs impacting mlxsw.

- Patches #1 and #2 fix issues in ACL handling error paths.
- Patch #3 fixes stack corruption in ACL code that a recent FW update
  has uncovered.

- Patch #4 fixes an issue in handling of IPIP next hops.

- Patch #5 fixes a typo in a the qos_pfc selftest
- Patch #6 fixes the same selftest to work with 8-lane ports.
====================

Link: https://lore.kernel.org/r/cover.1705502064.git.petrm@nvidia.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents f1172f3e b34f4de6
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -301,6 +301,7 @@ mlxsw_sp_acl_erp_table_alloc(struct mlxsw_sp_acl_erp_core *erp_core,
			     unsigned long *p_index)
{
	unsigned int num_rows, entry_size;
	unsigned long index;

	/* We only allow allocations of entire rows */
	if (num_erps % erp_core->num_erp_banks != 0)
@@ -309,10 +310,11 @@ mlxsw_sp_acl_erp_table_alloc(struct mlxsw_sp_acl_erp_core *erp_core,
	entry_size = erp_core->erpt_entries_size[region_type];
	num_rows = num_erps / erp_core->num_erp_banks;

	*p_index = gen_pool_alloc(erp_core->erp_tables, num_rows * entry_size);
	if (*p_index == 0)
	index = gen_pool_alloc(erp_core->erp_tables, num_rows * entry_size);
	if (!index)
		return -ENOBUFS;
	*p_index -= MLXSW_SP_ACL_ERP_GENALLOC_OFFSET;

	*p_index = index - MLXSW_SP_ACL_ERP_GENALLOC_OFFSET;

	return 0;
}
+4 −2
Original line number Diff line number Diff line
@@ -681,13 +681,13 @@ static void
mlxsw_sp_acl_tcam_region_destroy(struct mlxsw_sp *mlxsw_sp,
				 struct mlxsw_sp_acl_tcam_region *region)
{
	struct mlxsw_sp_acl_tcam *tcam = mlxsw_sp_acl_to_tcam(mlxsw_sp->acl);
	const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops;

	ops->region_fini(mlxsw_sp, region->priv);
	mlxsw_sp_acl_tcam_region_disable(mlxsw_sp, region);
	mlxsw_sp_acl_tcam_region_free(mlxsw_sp, region);
	mlxsw_sp_acl_tcam_region_id_put(region->group->tcam,
					region->id);
	mlxsw_sp_acl_tcam_region_id_put(tcam, region->id);
	kfree(region);
}

@@ -1564,6 +1564,8 @@ int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp,
	tcam->max_groups = max_groups;
	tcam->max_group_size = MLXSW_CORE_RES_GET(mlxsw_sp->core,
						  ACL_MAX_GROUP_SIZE);
	tcam->max_group_size = min_t(unsigned int, tcam->max_group_size,
				     MLXSW_REG_PAGT_ACL_MAX_NUM);

	err = ops->init(mlxsw_sp, tcam->priv, tcam);
	if (err)
+12 −12
Original line number Diff line number Diff line
@@ -11472,6 +11472,13 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp,
	if (err)
		goto err_register_netevent_notifier;

	mlxsw_sp->router->netdevice_nb.notifier_call =
		mlxsw_sp_router_netdevice_event;
	err = register_netdevice_notifier_net(mlxsw_sp_net(mlxsw_sp),
					      &mlxsw_sp->router->netdevice_nb);
	if (err)
		goto err_register_netdev_notifier;

	mlxsw_sp->router->nexthop_nb.notifier_call =
		mlxsw_sp_nexthop_obj_event;
	err = register_nexthop_notifier(mlxsw_sp_net(mlxsw_sp),
@@ -11487,22 +11494,15 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp,
	if (err)
		goto err_register_fib_notifier;

	mlxsw_sp->router->netdevice_nb.notifier_call =
		mlxsw_sp_router_netdevice_event;
	err = register_netdevice_notifier_net(mlxsw_sp_net(mlxsw_sp),
					      &mlxsw_sp->router->netdevice_nb);
	if (err)
		goto err_register_netdev_notifier;

	return 0;

err_register_netdev_notifier:
	unregister_fib_notifier(mlxsw_sp_net(mlxsw_sp),
				&mlxsw_sp->router->fib_nb);
err_register_fib_notifier:
	unregister_nexthop_notifier(mlxsw_sp_net(mlxsw_sp),
				    &mlxsw_sp->router->nexthop_nb);
err_register_nexthop_notifier:
	unregister_netdevice_notifier_net(mlxsw_sp_net(mlxsw_sp),
					  &router->netdevice_nb);
err_register_netdev_notifier:
	unregister_netevent_notifier(&mlxsw_sp->router->netevent_nb);
err_register_netevent_notifier:
	unregister_inet6addr_validator_notifier(&router->inet6addr_valid_nb);
@@ -11550,11 +11550,11 @@ void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp)
{
	struct mlxsw_sp_router *router = mlxsw_sp->router;

	unregister_netdevice_notifier_net(mlxsw_sp_net(mlxsw_sp),
					  &router->netdevice_nb);
	unregister_fib_notifier(mlxsw_sp_net(mlxsw_sp), &router->fib_nb);
	unregister_nexthop_notifier(mlxsw_sp_net(mlxsw_sp),
				    &router->nexthop_nb);
	unregister_netdevice_notifier_net(mlxsw_sp_net(mlxsw_sp),
					  &router->netdevice_nb);
	unregister_netevent_notifier(&router->netevent_nb);
	unregister_inet6addr_validator_notifier(&router->inet6addr_valid_nb);
	unregister_inetaddr_validator_notifier(&router->inetaddr_valid_nb);
+17 −2
Original line number Diff line number Diff line
@@ -40,7 +40,6 @@
# |   + $swp1          $swp3 +                    + $swp4                     |
# |   | iPOOL1        iPOOL0 |                    | iPOOL2                    |
# |   | ePOOL4        ePOOL5 |                    | ePOOL4                    |
# |   |                1Gbps |                    | 1Gbps                     |
# |   |        PFC:enabled=1 |                    | PFC:enabled=1             |
# | +-|----------------------|-+                +-|------------------------+  |
# | | + $swp1.111  $swp3.111 + |                | + $swp4.111              |  |
@@ -120,6 +119,9 @@ h2_destroy()

switch_create()
{
	local lanes_swp4
	local pg1_size

	# pools
	# -----

@@ -229,7 +231,20 @@ switch_create()
	dcb pfc set dev $swp4 prio-pfc all:off 1:on
	# PG0 will get autoconfigured to Xoff, give PG1 arbitrarily 100K, which
	# is (-2*MTU) about 80K of delay provision.
	dcb buffer set dev $swp4 buffer-size all:0 1:$_100KB
	pg1_size=$_100KB

	setup_wait_dev_with_timeout $swp4

	lanes_swp4=$(ethtool $swp4 | grep 'Lanes:')
	lanes_swp4=${lanes_swp4#*"Lanes: "}

	# 8-lane ports use two buffers among which the configured buffer
	# is split, so double the size to get twice (20K + 80K).
	if [[ $lanes_swp4 -eq 8 ]]; then
		pg1_size=$((pg1_size * 2))
	fi

	dcb buffer set dev $swp4 buffer-size all:0 1:$pg1_size

	# bridges
	# -------
+105 −1
Original line number Diff line number Diff line
@@ -10,7 +10,8 @@ lib_dir=$(dirname $0)/../../../../net/forwarding
ALL_TESTS="single_mask_test identical_filters_test two_masks_test \
	multiple_masks_test ctcam_edge_cases_test delta_simple_test \
	delta_two_masks_one_key_test delta_simple_rehash_test \
	bloom_simple_test bloom_complex_test bloom_delta_test"
	bloom_simple_test bloom_complex_test bloom_delta_test \
	max_erp_entries_test max_group_size_test"
NUM_NETIFS=2
source $lib_dir/lib.sh
source $lib_dir/tc_common.sh
@@ -983,6 +984,109 @@ bloom_delta_test()
	log_test "bloom delta test ($tcflags)"
}

max_erp_entries_test()
{
	# The number of eRP entries is limited. Once the maximum number of eRPs
	# has been reached, filters cannot be added. This test verifies that
	# when this limit is reached, inserstion fails without crashing.

	RET=0

	local num_masks=32
	local num_regions=15
	local chain_failed
	local mask_failed
	local ret

	if [[ "$tcflags" != "skip_sw" ]]; then
		return 0;
	fi

	for ((i=1; i < $num_regions; i++)); do
		for ((j=$num_masks; j >= 0; j--)); do
			tc filter add dev $h2 ingress chain $i protocol ip \
				pref $i	handle $j flower $tcflags \
				dst_ip 192.1.0.0/$j &> /dev/null
			ret=$?

			if [ $ret -ne 0 ]; then
				chain_failed=$i
				mask_failed=$j
				break 2
			fi
		done
	done

	# We expect to exceed the maximum number of eRP entries, so that
	# insertion eventually fails. Otherwise, the test should be adjusted to
	# add more filters.
	check_fail $ret "expected to exceed number of eRP entries"

	for ((; i >= 1; i--)); do
		for ((j=0; j <= $num_masks; j++)); do
			tc filter del dev $h2 ingress chain $i protocol ip \
				pref $i handle $j flower &> /dev/null
		done
	done

	log_test "max eRP entries test ($tcflags). " \
		"max chain $chain_failed, mask $mask_failed"
}

max_group_size_test()
{
	# The number of ACLs in an ACL group is limited. Once the maximum
	# number of ACLs has been reached, filters cannot be added. This test
	# verifies that when this limit is reached, insertion fails without
	# crashing.

	RET=0

	local num_acls=32
	local max_size
	local ret

	if [[ "$tcflags" != "skip_sw" ]]; then
		return 0;
	fi

	for ((i=1; i < $num_acls; i++)); do
		if [[ $(( i % 2 )) == 1 ]]; then
			tc filter add dev $h2 ingress pref $i proto ipv4 \
				flower $tcflags dst_ip 198.51.100.1/32 \
				ip_proto tcp tcp_flags 0x01/0x01 \
				action drop &> /dev/null
		else
			tc filter add dev $h2 ingress pref $i proto ipv6 \
				flower $tcflags dst_ip 2001:db8:1::1/128 \
				action drop &> /dev/null
		fi

		ret=$?
		[[ $ret -ne 0 ]] && max_size=$((i - 1)) && break
	done

	# We expect to exceed the maximum number of ACLs in a group, so that
	# insertion eventually fails. Otherwise, the test should be adjusted to
	# add more filters.
	check_fail $ret "expected to exceed number of ACLs in a group"

	for ((; i >= 1; i--)); do
		if [[ $(( i % 2 )) == 1 ]]; then
			tc filter del dev $h2 ingress pref $i proto ipv4 \
				flower $tcflags dst_ip 198.51.100.1/32 \
				ip_proto tcp tcp_flags 0x01/0x01 \
				action drop &> /dev/null
		else
			tc filter del dev $h2 ingress pref $i proto ipv6 \
				flower $tcflags dst_ip 2001:db8:1::1/128 \
				action drop &> /dev/null
		fi
	done

	log_test "max ACL group size test ($tcflags). max size $max_size"
}

setup_prepare()
{
	h1=${NETIFS[p1]}