net/mlx5e: Guarantee room for XSK wakeup NOP on async ICOSQ
authorTariq Toukan <tariqt@nvidia.com>
Wed, 10 Feb 2021 12:58:01 +0000 (14:58 +0200)
committerSaeed Mahameed <saeedm@nvidia.com>
Wed, 31 Mar 2021 20:12:24 +0000 (13:12 -0700)
XSK wakeup flow triggers an IRQ by posting a NOP WQE and hitting
the doorbell on the async ICOSQ.
It maintains its state so that it doesn't issue another NOP WQE
if it has an outstanding one already.

For this flow to work properly, the NOP post must not fail.
Make sure to reserve room for the NOP WQE in all WQE posts to the
async ICOSQ.

Fixes: 8d94b590f1e4 ("net/mlx5e: Turn XSK ICOSQ into a general asynchronous one")
Fixes: 1182f3659357 ("net/mlx5e: kTLS, Add kTLS RX HW offload support")
Fixes: 0419d8c9d8f8 ("net/mlx5e: kTLS, Add kTLS RX resync support")
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Reviewed-by: Maxim Mikityanskiy <maximmi@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
drivers/net/ethernet/mellanox/mlx5/core/en.h
drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_rx.c
drivers/net/ethernet/mellanox/mlx5/core/en_main.c

index 304b296fe8b989210824b62606bd934b0972c9c4..bc6f77ea0a31f1f2a945e7a87d221cf331300970 100644 (file)
@@ -516,6 +516,7 @@ struct mlx5e_icosq {
        struct mlx5_wq_cyc         wq;
        void __iomem              *uar_map;
        u32                        sqn;
+       u16                        reserved_room;
        unsigned long              state;
 
        /* control path */
index 2371b83dad9ca86e344795535ae31572135325e2..055c3bc2373393dd656ef8a03372f02c81fd6aaf 100644 (file)
@@ -441,4 +441,10 @@ static inline u16 mlx5e_stop_room_for_wqe(u16 wqe_size)
        return wqe_size * 2 - 1;
 }
 
+static inline bool mlx5e_icosq_can_post_wqe(struct mlx5e_icosq *sq, u16 wqe_size)
+{
+       u16 room = sq->reserved_room + mlx5e_stop_room_for_wqe(wqe_size);
+
+       return mlx5e_wqc_has_room_for(&sq->wq, sq->cc, sq->pc, room);
+}
 #endif
index 57c5ebd597a79140e3f7a23d02fa602cddb05c0a..19d22a63313f38e7cabae20a5e31898a5f426f7b 100644 (file)
@@ -138,11 +138,10 @@ post_static_params(struct mlx5e_icosq *sq,
 {
        struct mlx5e_set_tls_static_params_wqe *wqe;
        struct mlx5e_icosq_wqe_info wi;
-       u16 pi, num_wqebbs, room;
+       u16 pi, num_wqebbs;
 
        num_wqebbs = MLX5E_TLS_SET_STATIC_PARAMS_WQEBBS;
-       room = mlx5e_stop_room_for_wqe(num_wqebbs);
-       if (unlikely(!mlx5e_wqc_has_room_for(&sq->wq, sq->cc, sq->pc, room)))
+       if (unlikely(!mlx5e_icosq_can_post_wqe(sq, num_wqebbs)))
                return ERR_PTR(-ENOSPC);
 
        pi = mlx5e_icosq_get_next_pi(sq, num_wqebbs);
@@ -169,11 +168,10 @@ post_progress_params(struct mlx5e_icosq *sq,
 {
        struct mlx5e_set_tls_progress_params_wqe *wqe;
        struct mlx5e_icosq_wqe_info wi;
-       u16 pi, num_wqebbs, room;
+       u16 pi, num_wqebbs;
 
        num_wqebbs = MLX5E_TLS_SET_PROGRESS_PARAMS_WQEBBS;
-       room = mlx5e_stop_room_for_wqe(num_wqebbs);
-       if (unlikely(!mlx5e_wqc_has_room_for(&sq->wq, sq->cc, sq->pc, room)))
+       if (unlikely(!mlx5e_icosq_can_post_wqe(sq, num_wqebbs)))
                return ERR_PTR(-ENOSPC);
 
        pi = mlx5e_icosq_get_next_pi(sq, num_wqebbs);
@@ -278,17 +276,15 @@ resync_post_get_progress_params(struct mlx5e_icosq *sq,
 
        buf->priv_rx = priv_rx;
 
-       BUILD_BUG_ON(MLX5E_KTLS_GET_PROGRESS_WQEBBS != 1);
-
        spin_lock_bh(&sq->channel->async_icosq_lock);
 
-       if (unlikely(!mlx5e_wqc_has_room_for(&sq->wq, sq->cc, sq->pc, 1))) {
+       if (unlikely(!mlx5e_icosq_can_post_wqe(sq, MLX5E_KTLS_GET_PROGRESS_WQEBBS))) {
                spin_unlock_bh(&sq->channel->async_icosq_lock);
                err = -ENOSPC;
                goto err_dma_unmap;
        }
 
-       pi = mlx5e_icosq_get_next_pi(sq, 1);
+       pi = mlx5e_icosq_get_next_pi(sq, MLX5E_KTLS_GET_PROGRESS_WQEBBS);
        wqe = MLX5E_TLS_FETCH_GET_PROGRESS_PARAMS_WQE(sq, pi);
 
 #define GET_PSV_DS_CNT (DIV_ROUND_UP(sizeof(*wqe), MLX5_SEND_WQE_DS))
@@ -308,7 +304,7 @@ resync_post_get_progress_params(struct mlx5e_icosq *sq,
 
        wi = (struct mlx5e_icosq_wqe_info) {
                .wqe_type = MLX5E_ICOSQ_WQE_GET_PSV_TLS,
-               .num_wqebbs = 1,
+               .num_wqebbs = MLX5E_KTLS_GET_PROGRESS_WQEBBS,
                .tls_get_params.buf = buf,
        };
        icosq_fill_wi(sq, pi, &wi);
index 158f947a85031ea0147e5d50f8c259813f87733a..5db63b9f3b70d99a36d2f6a6e6043ee6f085b74f 100644 (file)
@@ -1091,6 +1091,7 @@ static int mlx5e_alloc_icosq(struct mlx5e_channel *c,
 
        sq->channel   = c;
        sq->uar_map   = mdev->mlx5e_res.bfreg.map;
+       sq->reserved_room = param->stop_room;
 
        param->wq.db_numa_node = cpu_to_node(c->cpu);
        err = mlx5_wq_cyc_create(mdev, &param->wq, sqc_wq, wq, &sq->wq_ctrl);
@@ -2350,6 +2351,24 @@ void mlx5e_build_icosq_param(struct mlx5e_priv *priv,
        mlx5e_build_ico_cq_param(priv, log_wq_size, &param->cqp);
 }
 
+static void mlx5e_build_async_icosq_param(struct mlx5e_priv *priv,
+                                         struct mlx5e_params *params,
+                                         u8 log_wq_size,
+                                         struct mlx5e_sq_param *param)
+{
+       void *sqc = param->sqc;
+       void *wq = MLX5_ADDR_OF(sqc, sqc, wq);
+
+       mlx5e_build_sq_param_common(priv, param);
+
+       /* async_icosq is used by XSK only if xdp_prog is active */
+       if (params->xdp_prog)
+               param->stop_room = mlx5e_stop_room_for_wqe(1); /* for XSK NOP */
+       MLX5_SET(sqc, sqc, reg_umr, MLX5_CAP_ETH(priv->mdev, reg_umr_sq));
+       MLX5_SET(wq, wq, log_wq_sz, log_wq_size);
+       mlx5e_build_ico_cq_param(priv, log_wq_size, &param->cqp);
+}
+
 void mlx5e_build_xdpsq_param(struct mlx5e_priv *priv,
                             struct mlx5e_params *params,
                             struct mlx5e_sq_param *param)
@@ -2398,7 +2417,7 @@ static void mlx5e_build_channel_param(struct mlx5e_priv *priv,
        mlx5e_build_sq_param(priv, params, &cparam->txq_sq);
        mlx5e_build_xdpsq_param(priv, params, &cparam->xdp_sq);
        mlx5e_build_icosq_param(priv, icosq_log_wq_sz, &cparam->icosq);
-       mlx5e_build_icosq_param(priv, async_icosq_log_wq_sz, &cparam->async_icosq);
+       mlx5e_build_async_icosq_param(priv, params, async_icosq_log_wq_sz, &cparam->async_icosq);
 }
 
 int mlx5e_open_channels(struct mlx5e_priv *priv,