From: Carolina Jubran During channel activation, mlx5e_activate_channels() triggers the ICOSQ once for every channel in order to kick NAPI. mlx5e_trigger_napi_icosq() sets MLX5E_SQ_STATE_LOCK_NEEDED and waits for an RCU grace period before serializing the trigger with ICOSQ users in NAPI context. Mark all channel ICOSQs as requiring locking first, wait for a single grace period, and then trigger all of them. Keep mlx5e_trigger_napi_icosq() with its existing synchronization semantics for standalone callers. 248 channels, rcu_normal=1, ip link set eth2 up: Before: 3.095s After: 1.794s (~1.7x faster) Signed-off-by: Carolina Jubran Signed-off-by: Tariq Toukan --- .../net/ethernet/mellanox/mlx5/core/en_main.c | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index fe4e5d0b2e9a..58e4874b664f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -2837,14 +2837,11 @@ static int mlx5e_channel_stats_alloc(struct mlx5e_priv *priv, int ix, int cpu) return 0; } -void mlx5e_trigger_napi_icosq(struct mlx5e_channel *c) +static void mlx5e_trigger_napi_icosq_post_sync(struct mlx5e_channel *c) { struct mlx5e_icosq *sq = &c->icosq; bool locked; - set_bit(MLX5E_SQ_STATE_LOCK_NEEDED, &sq->state); - synchronize_net(); - locked = mlx5e_icosq_sync_lock(sq); mlx5e_trigger_irq(sq); mlx5e_icosq_sync_unlock(sq, locked); @@ -2852,6 +2849,13 @@ void mlx5e_trigger_napi_icosq(struct mlx5e_channel *c) clear_bit(MLX5E_SQ_STATE_LOCK_NEEDED, &sq->state); } +void mlx5e_trigger_napi_icosq(struct mlx5e_channel *c) +{ + set_bit(MLX5E_SQ_STATE_LOCK_NEEDED, &c->icosq.state); + synchronize_net(); + mlx5e_trigger_napi_icosq_post_sync(c); +} + void mlx5e_trigger_napi_async_icosq(struct mlx5e_channel *c) { struct mlx5e_icosq *sq = c->async_icosq; @@ -3099,6 +3103,19 @@ int mlx5e_open_channels(struct mlx5e_priv *priv, return err; } +static void mlx5e_trigger_napi_icosqs(struct mlx5e_channels *chs) +{ + int i; + + for (i = 0; i < chs->num; i++) + set_bit(MLX5E_SQ_STATE_LOCK_NEEDED, &chs->c[i]->icosq.state); + + synchronize_net(); + + for (i = 0; i < chs->num; i++) + mlx5e_trigger_napi_icosq_post_sync(chs->c[i]); +} + static void mlx5e_activate_channels(struct mlx5e_priv *priv, struct mlx5e_channels *chs) { int i; @@ -3109,8 +3126,7 @@ static void mlx5e_activate_channels(struct mlx5e_priv *priv, struct mlx5e_channe if (priv->htb) mlx5e_qos_activate_queues(priv); - for (i = 0; i < chs->num; i++) - mlx5e_trigger_napi_icosq(chs->c[i]); + mlx5e_trigger_napi_icosqs(chs); if (chs->ptp) mlx5e_ptp_activate_channel(chs->ptp); -- 2.44.0