Commit 94c4fed7 authored by Saeed Mahameed's avatar Saeed Mahameed
Browse files

net/mlx5e: kTLS, Avoid kzalloc(GFP_KERNEL) under spinlock



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: 0419d8c9 ("net/mlx5e: kTLS, Add kTLS RX resync support")
Reported-by: default avatarYueHaibing <yuehaibing@huawei.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
Reviewed-by: default avatarTariq Toukan <tariqt@nvidia.com>
parent 581642f3
Loading
Loading
Loading
Loading
+10 −15
Original line number Diff line number Diff line
@@ -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,