| From a2faf150514ee4a652fafe17c2dcb05efa261f8d Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Mon, 6 Feb 2023 11:52:02 +0200 |
| Subject: net/mlx5: E-switch, Devcom, sync devcom events and devcom comp |
| register |
| |
| From: Shay Drory <shayd@nvidia.com> |
| |
| [ Upstream commit 8c253dfc89efde6b5faddf9e7400e5d17884e042 ] |
| |
| devcom events are sent to all registered component. Following the |
| cited patch, it is possible for two components, e.g.: two eswitches, |
| to send devcom events, while both components are registered. This |
| means eswitch layer will do double un/pairing, which is double |
| allocation and free of resources, even though only one un/pairing is |
| needed. flow example: |
| |
| cpu0 cpu1 |
| ---- ---- |
| |
| mlx5_devlink_eswitch_mode_set(dev0) |
| esw_offloads_devcom_init() |
| mlx5_devcom_register_component(esw0) |
| mlx5_devlink_eswitch_mode_set(dev1) |
| esw_offloads_devcom_init() |
| mlx5_devcom_register_component(esw1) |
| mlx5_devcom_send_event() |
| mlx5_devcom_send_event() |
| |
| Hence, check whether the eswitches are already un/paired before |
| free/allocation of resources. |
| |
| Fixes: 09b278462f16 ("net: devlink: enable parallel ops on netlink interface") |
| Signed-off-by: Shay Drory <shayd@nvidia.com> |
| Reviewed-by: Mark Bloch <mbloch@nvidia.com> |
| Signed-off-by: Saeed Mahameed <saeedm@nvidia.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/net/ethernet/mellanox/mlx5/core/eswitch.h | 1 + |
| .../net/ethernet/mellanox/mlx5/core/eswitch_offloads.c | 9 ++++++++- |
| 2 files changed, 9 insertions(+), 1 deletion(-) |
| |
| diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h |
| index 821c78bab3732..a3daca44f74b1 100644 |
| --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h |
| +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h |
| @@ -340,6 +340,7 @@ struct mlx5_eswitch { |
| } params; |
| struct blocking_notifier_head n_head; |
| struct dentry *dbgfs; |
| + bool paired[MLX5_MAX_PORTS]; |
| }; |
| |
| void esw_offloads_disable(struct mlx5_eswitch *esw); |
| diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c |
| index 5235b5a7b9637..433cdd0a2cf34 100644 |
| --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c |
| +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c |
| @@ -2827,6 +2827,9 @@ static int mlx5_esw_offloads_devcom_event(int event, |
| mlx5_eswitch_vport_match_metadata_enabled(peer_esw)) |
| break; |
| |
| + if (esw->paired[mlx5_get_dev_index(peer_esw->dev)]) |
| + break; |
| + |
| err = mlx5_esw_offloads_set_ns_peer(esw, peer_esw, true); |
| if (err) |
| goto err_out; |
| @@ -2838,14 +2841,18 @@ static int mlx5_esw_offloads_devcom_event(int event, |
| if (err) |
| goto err_pair; |
| |
| + esw->paired[mlx5_get_dev_index(peer_esw->dev)] = true; |
| + peer_esw->paired[mlx5_get_dev_index(esw->dev)] = true; |
| mlx5_devcom_set_paired(devcom, MLX5_DEVCOM_ESW_OFFLOADS, true); |
| break; |
| |
| case ESW_OFFLOADS_DEVCOM_UNPAIR: |
| - if (!mlx5_devcom_is_paired(devcom, MLX5_DEVCOM_ESW_OFFLOADS)) |
| + if (!esw->paired[mlx5_get_dev_index(peer_esw->dev)]) |
| break; |
| |
| mlx5_devcom_set_paired(devcom, MLX5_DEVCOM_ESW_OFFLOADS, false); |
| + esw->paired[mlx5_get_dev_index(peer_esw->dev)] = false; |
| + peer_esw->paired[mlx5_get_dev_index(esw->dev)] = false; |
| mlx5_esw_offloads_unpair(peer_esw); |
| mlx5_esw_offloads_unpair(esw); |
| mlx5_esw_offloads_set_ns_peer(esw, peer_esw, false); |
| -- |
| 2.39.2 |
| |