Skip to content

Commit 982c3e2

Browse files
committed
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 4b7a632 ("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: David S. Miller <[email protected]>
2 parents e42134b + ed62af4 commit 982c3e2

File tree

14 files changed

+283
-19
lines changed

14 files changed

+283
-19
lines changed

drivers/net/ethernet/mellanox/mlxsw/spectrum.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3580,6 +3580,25 @@ mlxsw_sp_resources_rif_mac_profile_register(struct mlxsw_core *mlxsw_core)
35803580
&size_params);
35813581
}
35823582

3583+
static int mlxsw_sp_resources_rifs_register(struct mlxsw_core *mlxsw_core)
3584+
{
3585+
struct devlink *devlink = priv_to_devlink(mlxsw_core);
3586+
struct devlink_resource_size_params size_params;
3587+
u64 max_rifs;
3588+
3589+
if (!MLXSW_CORE_RES_VALID(mlxsw_core, MAX_RIFS))
3590+
return -EIO;
3591+
3592+
max_rifs = MLXSW_CORE_RES_GET(mlxsw_core, MAX_RIFS);
3593+
devlink_resource_size_params_init(&size_params, max_rifs, max_rifs,
3594+
1, DEVLINK_RESOURCE_UNIT_ENTRY);
3595+
3596+
return devlink_resource_register(devlink, "rifs", max_rifs,
3597+
MLXSW_SP_RESOURCE_RIFS,
3598+
DEVLINK_RESOURCE_ID_PARENT_TOP,
3599+
&size_params);
3600+
}
3601+
35833602
static int mlxsw_sp1_resources_register(struct mlxsw_core *mlxsw_core)
35843603
{
35853604
int err;
@@ -3604,8 +3623,13 @@ static int mlxsw_sp1_resources_register(struct mlxsw_core *mlxsw_core)
36043623
if (err)
36053624
goto err_resources_rif_mac_profile_register;
36063625

3626+
err = mlxsw_sp_resources_rifs_register(mlxsw_core);
3627+
if (err)
3628+
goto err_resources_rifs_register;
3629+
36073630
return 0;
36083631

3632+
err_resources_rifs_register:
36093633
err_resources_rif_mac_profile_register:
36103634
err_policer_resources_register:
36113635
err_resources_counter_register:
@@ -3638,8 +3662,13 @@ static int mlxsw_sp2_resources_register(struct mlxsw_core *mlxsw_core)
36383662
if (err)
36393663
goto err_resources_rif_mac_profile_register;
36403664

3665+
err = mlxsw_sp_resources_rifs_register(mlxsw_core);
3666+
if (err)
3667+
goto err_resources_rifs_register;
3668+
36413669
return 0;
36423670

3671+
err_resources_rifs_register:
36433672
err_resources_rif_mac_profile_register:
36443673
err_policer_resources_register:
36453674
err_resources_counter_register:

drivers/net/ethernet/mellanox/mlxsw/spectrum.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ enum mlxsw_sp_resource_id {
6868
MLXSW_SP_RESOURCE_GLOBAL_POLICERS,
6969
MLXSW_SP_RESOURCE_SINGLE_RATE_POLICERS,
7070
MLXSW_SP_RESOURCE_RIF_MAC_PROFILES,
71+
MLXSW_SP_RESOURCE_RIFS,
7172
};
7273

7374
struct mlxsw_sp_port;

drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8134,6 +8134,7 @@ mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp,
81348134
mlxsw_sp_rif_counters_alloc(rif);
81358135
}
81368136

8137+
atomic_inc(&mlxsw_sp->router->rifs_count);
81378138
return rif;
81388139

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

8167+
atomic_dec(&mlxsw_sp->router->rifs_count);
81668168
mlxsw_sp_router_rif_gone_sync(mlxsw_sp, rif);
81678169
vr = &mlxsw_sp->router->vrs[rif->vr_id];
81688170

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

8326+
static u64 mlxsw_sp_rifs_occ_get(void *priv)
8327+
{
8328+
const struct mlxsw_sp *mlxsw_sp = priv;
8329+
8330+
return atomic_read(&mlxsw_sp->router->rifs_count);
8331+
}
8332+
83248333
static struct mlxsw_sp_rif_mac_profile *
83258334
mlxsw_sp_rif_mac_profile_create(struct mlxsw_sp *mlxsw_sp, const char *mac,
83268335
struct netlink_ext_ack *extack)
@@ -9652,6 +9661,7 @@ mlxsw_sp_ul_rif_create(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_vr *vr,
96529661
if (err)
96539662
goto ul_rif_op_err;
96549663

9664+
atomic_inc(&mlxsw_sp->router->rifs_count);
96559665
return ul_rif;
96569666

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

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

98209831
idr_init(&mlxsw_sp->router->rif_mac_profiles_idr);
98219832
atomic_set(&mlxsw_sp->router->rif_mac_profiles_count, 0);
9833+
atomic_set(&mlxsw_sp->router->rifs_count, 0);
98229834
devlink_resource_occ_get_register(devlink,
98239835
MLXSW_SP_RESOURCE_RIF_MAC_PROFILES,
98249836
mlxsw_sp_rif_mac_profiles_occ_get,
98259837
mlxsw_sp);
9838+
devlink_resource_occ_get_register(devlink,
9839+
MLXSW_SP_RESOURCE_RIFS,
9840+
mlxsw_sp_rifs_occ_get,
9841+
mlxsw_sp);
98269842

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

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

9855+
devlink_resource_occ_get_unregister(devlink, MLXSW_SP_RESOURCE_RIFS);
98389856
devlink_resource_occ_get_unregister(devlink,
98399857
MLXSW_SP_RESOURCE_RIF_MAC_PROFILES);
98409858
WARN_ON(!idr_is_empty(&mlxsw_sp->router->rif_mac_profiles_idr));

drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ struct mlxsw_sp_router {
2020
struct mlxsw_sp_rif **rifs;
2121
struct idr rif_mac_profiles_idr;
2222
atomic_t rif_mac_profiles_count;
23+
atomic_t rifs_count;
2324
u8 max_rif_mac_profile;
2425
struct mlxsw_sp_vr *vrs;
2526
struct rhashtable neigh_ht;

drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -953,16 +953,16 @@ static const struct mlxsw_sp_trap_item mlxsw_sp_trap_items_arr[] = {
953953
.trap = MLXSW_SP_TRAP_CONTROL(ARP_REQUEST, NEIGH_DISCOVERY,
954954
MIRROR),
955955
.listeners_arr = {
956-
MLXSW_SP_RXL_MARK(ARPBC, NEIGH_DISCOVERY, MIRROR_TO_CPU,
957-
false),
956+
MLXSW_SP_RXL_MARK(ROUTER_ARPBC, NEIGH_DISCOVERY,
957+
TRAP_TO_CPU, false),
958958
},
959959
},
960960
{
961961
.trap = MLXSW_SP_TRAP_CONTROL(ARP_RESPONSE, NEIGH_DISCOVERY,
962962
MIRROR),
963963
.listeners_arr = {
964-
MLXSW_SP_RXL_MARK(ARPUC, NEIGH_DISCOVERY, MIRROR_TO_CPU,
965-
false),
964+
MLXSW_SP_RXL_MARK(ROUTER_ARPUC, NEIGH_DISCOVERY,
965+
TRAP_TO_CPU, false),
966966
},
967967
},
968968
{

drivers/net/ethernet/mellanox/mlxsw/trap.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ enum {
2727
MLXSW_TRAP_ID_PKT_SAMPLE = 0x38,
2828
MLXSW_TRAP_ID_FID_MISS = 0x3D,
2929
MLXSW_TRAP_ID_DECAP_ECN0 = 0x40,
30-
MLXSW_TRAP_ID_ARPBC = 0x50,
31-
MLXSW_TRAP_ID_ARPUC = 0x51,
3230
MLXSW_TRAP_ID_MTUERROR = 0x52,
3331
MLXSW_TRAP_ID_TTLERROR = 0x53,
3432
MLXSW_TRAP_ID_LBERROR = 0x54,
@@ -71,6 +69,8 @@ enum {
7169
MLXSW_TRAP_ID_IPV6_BFD = 0xD1,
7270
MLXSW_TRAP_ID_ROUTER_ALERT_IPV4 = 0xD6,
7371
MLXSW_TRAP_ID_ROUTER_ALERT_IPV6 = 0xD7,
72+
MLXSW_TRAP_ID_ROUTER_ARPBC = 0xE0,
73+
MLXSW_TRAP_ID_ROUTER_ARPUC = 0xE1,
7474
MLXSW_TRAP_ID_DISCARD_NON_ROUTABLE = 0x11A,
7575
MLXSW_TRAP_ID_DISCARD_ROUTER2 = 0x130,
7676
MLXSW_TRAP_ID_DISCARD_ROUTER3 = 0x131,
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# SPDX-License-Identifier: GPL-2.0
2+
3+
RIF_COUNTER_NUM_NETIFS=2
4+
5+
rif_counter_addr4()
6+
{
7+
local i=$1; shift
8+
local p=$1; shift
9+
10+
printf 192.0.%d.%d $((i / 64)) $(((4 * i % 256) + p))
11+
}
12+
13+
rif_counter_addr4pfx()
14+
{
15+
rif_counter_addr4 $@
16+
printf /30
17+
}
18+
19+
rif_counter_h1_create()
20+
{
21+
simple_if_init $h1
22+
}
23+
24+
rif_counter_h1_destroy()
25+
{
26+
simple_if_fini $h1
27+
}
28+
29+
rif_counter_h2_create()
30+
{
31+
simple_if_init $h2
32+
}
33+
34+
rif_counter_h2_destroy()
35+
{
36+
simple_if_fini $h2
37+
}
38+
39+
rif_counter_setup_prepare()
40+
{
41+
h1=${NETIFS[p1]}
42+
h2=${NETIFS[p2]}
43+
44+
vrf_prepare
45+
46+
rif_counter_h1_create
47+
rif_counter_h2_create
48+
}
49+
50+
rif_counter_cleanup()
51+
{
52+
local count=$1; shift
53+
54+
pre_cleanup
55+
56+
for ((i = 1; i <= count; i++)); do
57+
vlan_destroy $h2 $i
58+
done
59+
60+
rif_counter_h2_destroy
61+
rif_counter_h1_destroy
62+
63+
vrf_cleanup
64+
65+
if [[ -v RIF_COUNTER_BATCH_FILE ]]; then
66+
rm -f $RIF_COUNTER_BATCH_FILE
67+
fi
68+
}
69+
70+
71+
rif_counter_test()
72+
{
73+
local count=$1; shift
74+
local should_fail=$1; shift
75+
76+
RIF_COUNTER_BATCH_FILE="$(mktemp)"
77+
78+
for ((i = 1; i <= count; i++)); do
79+
vlan_create $h2 $i v$h2 $(rif_counter_addr4pfx $i 2)
80+
done
81+
for ((i = 1; i <= count; i++)); do
82+
cat >> $RIF_COUNTER_BATCH_FILE <<-EOF
83+
stats set dev $h2.$i l3_stats on
84+
EOF
85+
done
86+
87+
ip -b $RIF_COUNTER_BATCH_FILE
88+
check_err_fail $should_fail $? "RIF counter enablement"
89+
}
90+
91+
rif_counter_traffic_test()
92+
{
93+
local count=$1; shift
94+
local i;
95+
96+
for ((i = count; i > 0; i /= 2)); do
97+
$MZ $h1 -Q $i -c 1 -d 20msec -p 100 -a own -b $(mac_get $h2) \
98+
-A $(rif_counter_addr4 $i 1) \
99+
-B $(rif_counter_addr4 $i 2) \
100+
-q -t udp sp=54321,dp=12345
101+
done
102+
for ((i = count; i > 0; i /= 2)); do
103+
busywait "$TC_HIT_TIMEOUT" until_counter_is "== 1" \
104+
hw_stats_get l3_stats $h2.$i rx packets > /dev/null
105+
check_err $? "Traffic not seen at RIF $h2.$i"
106+
done
107+
}

tools/testing/selftests/drivers/net/mlxsw/spectrum-2/resource_scale.sh

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,16 @@ cleanup()
2525

2626
trap cleanup EXIT
2727

28-
ALL_TESTS="router tc_flower mirror_gre tc_police port rif_mac_profile"
28+
ALL_TESTS="
29+
router
30+
tc_flower
31+
mirror_gre
32+
tc_police
33+
port
34+
rif_mac_profile
35+
rif_counter
36+
"
37+
2938
for current_test in ${TESTS:-$ALL_TESTS}; do
3039
RET_FIN=0
3140
source ${current_test}_scale.sh
@@ -36,16 +45,32 @@ for current_test in ${TESTS:-$ALL_TESTS}; do
3645
for should_fail in 0 1; do
3746
RET=0
3847
target=$(${current_test}_get_target "$should_fail")
48+
if ((target == 0)); then
49+
log_test_skip "'$current_test' should_fail=$should_fail test"
50+
continue
51+
fi
52+
3953
${current_test}_setup_prepare
4054
setup_wait $num_netifs
55+
# Update target in case occupancy of a certain resource changed
56+
# following the test setup.
57+
target=$(${current_test}_get_target "$should_fail")
4158
${current_test}_test "$target" "$should_fail"
42-
${current_test}_cleanup
43-
devlink_reload
4459
if [[ "$should_fail" -eq 0 ]]; then
4560
log_test "'$current_test' $target"
61+
62+
if ((!RET)); then
63+
tt=${current_test}_traffic_test
64+
if [[ $(type -t $tt) == "function" ]]; then
65+
$tt "$target"
66+
log_test "'$current_test' $target traffic test"
67+
fi
68+
fi
4669
else
4770
log_test "'$current_test' overflow $target"
4871
fi
72+
${current_test}_cleanup $target
73+
devlink_reload
4974
RET_FIN=$(( RET_FIN || RET ))
5075
done
5176
done
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../spectrum/rif_counter_scale.sh

tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower_scale.sh

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,22 @@ source ../tc_flower_scale.sh
44
tc_flower_get_target()
55
{
66
local should_fail=$1; shift
7+
local max_cnts
78

89
# The driver associates a counter with each tc filter, which means the
910
# number of supported filters is bounded by the number of available
1011
# counters.
11-
# Currently, the driver supports 30K (30,720) flow counters and six of
12-
# these are used for multicast routing.
13-
local target=30714
12+
max_cnts=$(devlink_resource_size_get counters flow)
13+
14+
# Remove already allocated counters.
15+
((max_cnts -= $(devlink_resource_occ_get counters flow)))
16+
17+
# Each rule uses two counters, for packets and bytes.
18+
((max_cnts /= 2))
1419

1520
if ((! should_fail)); then
16-
echo $target
21+
echo $max_cnts
1722
else
18-
echo $((target + 1))
23+
echo $((max_cnts + 1))
1924
fi
2025
}

0 commit comments

Comments
 (0)