Skip to content

Commit 35c3569

Browse files
idoschkuba-moo
authored andcommitted
mlxsw: spectrum: Fix incorrect parsing depth after reload
Spectrum ASICs have a configurable limit on how deep into the packet they parse. By default, the limit is 96 bytes. There are several cases where this parsing depth is not enough and there is a need to increase it. For example, timestamping of PTP packets and a FIB multipath hash policy that requires hashing on inner fields. The driver therefore maintains a reference count that reflects the number of consumers that require an increased parsing depth. During reload_down() the parsing depth reference count does not necessarily drop to zero, but the parsing depth itself is restored to the default during reload_up() when the firmware is reset. It is therefore possible to end up in situations where the driver thinks that the parsing depth was increased (reference count is non-zero), when it is not. Fix by making sure that all the consumers that increase the parsing depth reference count also decrease it during reload_down(). Specifically, make sure that when the routing code is de-initialized it drops the reference count if it was increased because of a FIB multipath hash policy that requires hashing on inner fields. Add a warning if the reference count is not zero after the driver was de-initialized and explicitly reset it to zero during initialization for good measures. Fixes: 2d91f08 ("mlxsw: spectrum: Add infrastructure for parsing configuration") Reported-by: Maksym Yaremchuk <[email protected]> Signed-off-by: Ido Schimmel <[email protected]> Signed-off-by: Petr Machata <[email protected]> Link: https://lore.kernel.org/r/9c35e1b3e6c1d8f319a2449d14e2b86373f3b3ba.1678727526.git.petrm@nvidia.com Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 5ce76fe commit 35c3569

File tree

2 files changed

+16
-0
lines changed

2 files changed

+16
-0
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2937,6 +2937,7 @@ static int mlxsw_sp_netdevice_event(struct notifier_block *unused,
29372937

29382938
static void mlxsw_sp_parsing_init(struct mlxsw_sp *mlxsw_sp)
29392939
{
2940+
refcount_set(&mlxsw_sp->parsing.parsing_depth_ref, 0);
29402941
mlxsw_sp->parsing.parsing_depth = MLXSW_SP_DEFAULT_PARSING_DEPTH;
29412942
mlxsw_sp->parsing.vxlan_udp_dport = MLXSW_SP_DEFAULT_VXLAN_UDP_DPORT;
29422943
mutex_init(&mlxsw_sp->parsing.lock);
@@ -2945,6 +2946,7 @@ static void mlxsw_sp_parsing_init(struct mlxsw_sp *mlxsw_sp)
29452946
static void mlxsw_sp_parsing_fini(struct mlxsw_sp *mlxsw_sp)
29462947
{
29472948
mutex_destroy(&mlxsw_sp->parsing.lock);
2949+
WARN_ON_ONCE(refcount_read(&mlxsw_sp->parsing.parsing_depth_ref));
29482950
}
29492951

29502952
struct mlxsw_sp_ipv6_addr_node {

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10381,11 +10381,23 @@ static int mlxsw_sp_mp_hash_init(struct mlxsw_sp *mlxsw_sp)
1038110381
old_inc_parsing_depth);
1038210382
return err;
1038310383
}
10384+
10385+
static void mlxsw_sp_mp_hash_fini(struct mlxsw_sp *mlxsw_sp)
10386+
{
10387+
bool old_inc_parsing_depth = mlxsw_sp->router->inc_parsing_depth;
10388+
10389+
mlxsw_sp_mp_hash_parsing_depth_adjust(mlxsw_sp, old_inc_parsing_depth,
10390+
false);
10391+
}
1038410392
#else
1038510393
static int mlxsw_sp_mp_hash_init(struct mlxsw_sp *mlxsw_sp)
1038610394
{
1038710395
return 0;
1038810396
}
10397+
10398+
static void mlxsw_sp_mp_hash_fini(struct mlxsw_sp *mlxsw_sp)
10399+
{
10400+
}
1038910401
#endif
1039010402

1039110403
static int mlxsw_sp_dscp_init(struct mlxsw_sp *mlxsw_sp)
@@ -10615,6 +10627,7 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp,
1061510627
err_register_inetaddr_notifier:
1061610628
mlxsw_core_flush_owq();
1061710629
err_dscp_init:
10630+
mlxsw_sp_mp_hash_fini(mlxsw_sp);
1061810631
err_mp_hash_init:
1061910632
mlxsw_sp_neigh_fini(mlxsw_sp);
1062010633
err_neigh_init:
@@ -10655,6 +10668,7 @@ void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp)
1065510668
unregister_inet6addr_notifier(&mlxsw_sp->router->inet6addr_nb);
1065610669
unregister_inetaddr_notifier(&mlxsw_sp->router->inetaddr_nb);
1065710670
mlxsw_core_flush_owq();
10671+
mlxsw_sp_mp_hash_fini(mlxsw_sp);
1065810672
mlxsw_sp_neigh_fini(mlxsw_sp);
1065910673
mlxsw_sp_lb_rif_fini(mlxsw_sp);
1066010674
mlxsw_sp_vrs_fini(mlxsw_sp);

0 commit comments

Comments
 (0)