]> git.baikalelectronics.ru Git - kernel.git/commitdiff
net/mlx5e: kTLS, Avoid kzalloc(GFP_KERNEL) under spinlock
authorSaeed Mahameed <saeedm@nvidia.com>
Tue, 8 Sep 2020 05:54:43 +0000 (22:54 -0700)
committerSaeed Mahameed <saeedm@nvidia.com>
Tue, 22 Sep 2020 00:22:25 +0000 (17:22 -0700)
The spinlock only needed when accessing the channel's icosq, grab the lock
after the buf allocation in resync_post_get_progress_params() to avoid
kzalloc(GFP_KERNEL) in atomic context.

Fixes: d92bf3a50da0 ("net/mlx5e: kTLS, Add kTLS RX resync support")
Reported-by: YueHaibing <yuehaibing@huawei.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_rx.c

index e85411bd1fed32bf0583546ceb478e1c20437791..6bbfcf18107d2250e3ae291f8037535f67290d6e 100644 (file)
@@ -234,7 +234,7 @@ mlx5e_get_ktls_rx_priv_ctx(struct tls_context *tls_ctx)
 
 /* Re-sync */
 /* Runs in work context */
-static struct mlx5_wqe_ctrl_seg *
+static int
 resync_post_get_progress_params(struct mlx5e_icosq *sq,
                                struct mlx5e_ktls_offload_context_rx *priv_rx)
 {
@@ -264,7 +264,11 @@ 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(&sq->channel->async_icosq_lock);
+
        if (unlikely(!mlx5e_wqc_has_room_for(&sq->wq, sq->cc, sq->pc, 1))) {
+               spin_unlock(&sq->channel->async_icosq_lock);
                err = -ENOSPC;
                goto err_dma_unmap;
        }
@@ -294,8 +298,10 @@ resync_post_get_progress_params(struct mlx5e_icosq *sq,
        };
        icosq_fill_wi(sq, pi, &wi);
        sq->pc++;
+       mlx5e_notify_hw(&sq->wq, sq->pc, sq->uar_map, cseg);
+       spin_unlock(&sq->channel->async_icosq_lock);
 
-       return cseg;
+       return 0;
 
 err_dma_unmap:
        dma_unmap_single(pdev, buf->dma_addr, PROGRESS_PARAMS_PADDED_SIZE, DMA_FROM_DEVICE);
@@ -303,7 +309,7 @@ err_free:
        kfree(buf);
 err_out:
        priv_rx->stats->tls_resync_req_skip++;
-       return ERR_PTR(err);
+       return err;
 }
 
 /* Function is called with elevated refcount.
@@ -313,10 +319,8 @@ static void resync_handle_work(struct work_struct *work)
 {
        struct mlx5e_ktls_offload_context_rx *priv_rx;
        struct mlx5e_ktls_rx_resync_ctx *resync;
-       struct mlx5_wqe_ctrl_seg *cseg;
        struct mlx5e_channel *c;
        struct mlx5e_icosq *sq;
-       struct mlx5_wq_cyc *wq;
 
        resync = container_of(work, struct mlx5e_ktls_rx_resync_ctx, work);
        priv_rx = container_of(resync, struct mlx5e_ktls_offload_context_rx, resync);
@@ -328,18 +332,9 @@ static void resync_handle_work(struct work_struct *work)
 
        c = resync->priv->channels.c[priv_rx->rxq];
        sq = &c->async_icosq;
-       wq = &sq->wq;
 
-       spin_lock(&c->async_icosq_lock);
-
-       cseg = resync_post_get_progress_params(sq, priv_rx);
-       if (IS_ERR(cseg)) {
+       if (resync_post_get_progress_params(sq, priv_rx))
                refcount_dec(&resync->refcnt);
-               goto unlock;
-       }
-       mlx5e_notify_hw(wq, sq->pc, sq->uar_map, cseg);
-unlock:
-       spin_unlock(&c->async_icosq_lock);
 }
 
 static void resync_init(struct mlx5e_ktls_rx_resync_ctx *resync,