| From 7a52d6618afdf97173eab06a8c0e2616196468e2 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 31876db3c7641..5fd971cee6fdc 100644 |
| --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h |
| +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h |
| @@ -341,6 +341,7 @@ struct mlx5_eswitch { |
| u32 large_group_num; |
| } params; |
| struct blocking_notifier_head n_head; |
| + 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 727b30f3a229a..a60c9f292e10c 100644 |
| --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c |
| +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c |
| @@ -2744,6 +2744,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; |
| @@ -2755,14 +2758,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 |
| |