Commit 23fb09db authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'net-mlx5e-rx-datapath-enhancements'

Tariq Toukan says:

====================
net/mlx5e: RX datapath enhancements

This series by Dragos introduces multiple RX datapath enhancements to
the mlx5e driver.

First patch adds SW handling for oversized packets in non-linear SKB
mode.

Second patch adds a reclaim mechanism to mitigate memory allocation
failures with memory providers.
====================

Link: https://patch.msgid.link/20260203072130.1710255-1-tariqt@nvidia.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 14eb64db 09e6960e
Loading
Loading
Loading
Loading
+2 −23
Original line number Diff line number Diff line
@@ -4716,7 +4716,6 @@ int mlx5e_change_mtu(struct net_device *netdev, int new_mtu,
	struct mlx5e_priv *priv = netdev_priv(netdev);
	struct mlx5e_params new_params;
	struct mlx5e_params *params;
	bool reset = true;
	int err = 0;

	mutex_lock(&priv->state_lock);
@@ -4742,28 +4741,8 @@ int mlx5e_change_mtu(struct net_device *netdev, int new_mtu,
		goto out;
	}

	if (params->packet_merge.type == MLX5E_PACKET_MERGE_LRO)
		reset = false;

	if (params->rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ &&
	    params->packet_merge.type != MLX5E_PACKET_MERGE_SHAMPO) {
		bool is_linear_old = mlx5e_rx_mpwqe_is_linear_skb(priv->mdev, params, NULL);
		bool is_linear_new = mlx5e_rx_mpwqe_is_linear_skb(priv->mdev,
								  &new_params, NULL);
		u8 sz_old = mlx5e_mpwqe_get_log_rq_size(priv->mdev, params, NULL);
		u8 sz_new = mlx5e_mpwqe_get_log_rq_size(priv->mdev, &new_params, NULL);

		/* Always reset in linear mode - hw_mtu is used in data path.
		 * Check that the mode was non-linear and didn't change.
		 * If XSK is active, XSK RQs are linear.
		 * Reset if the RQ size changed, even if it's non-linear.
		 */
		if (!is_linear_old && !is_linear_new && !priv->xsk.refcnt &&
		    sz_old == sz_new)
			reset = false;
	}

	err = mlx5e_safe_switch_params(priv, &new_params, preactivate, NULL, reset);
	err = mlx5e_safe_switch_params(priv, &new_params, preactivate, NULL,
				       true);

out:
	WRITE_ONCE(netdev->mtu, params->sw_mtu);
+34 −3
Original line number Diff line number Diff line
@@ -1087,11 +1087,24 @@ int mlx5e_poll_ico_cq(struct mlx5e_cq *cq)
	return i;
}

static void mlx5e_reclaim_mpwqe_pages(struct mlx5e_rq *rq, int head,
				      int reclaim)
{
	struct mlx5_wq_ll *wq = &rq->mpwqe.wq;

	for (int i = 0; i < reclaim; i++) {
		head = mlx5_wq_ll_get_wqe_next_ix(wq, head);

		mlx5e_dealloc_rx_mpwqe(rq, head);
	}
}

INDIRECT_CALLABLE_SCOPE bool mlx5e_post_rx_mpwqes(struct mlx5e_rq *rq)
{
	struct mlx5_wq_ll *wq = &rq->mpwqe.wq;
	u8  umr_completed = rq->mpwqe.umr_completed;
	struct mlx5e_icosq *sq = rq->icosq;
	bool reclaimed = false;
	int alloc_err = 0;
	u8  missing, i;
	u16 head;
@@ -1126,11 +1139,20 @@ INDIRECT_CALLABLE_SCOPE bool mlx5e_post_rx_mpwqes(struct mlx5e_rq *rq)
		/* Deferred free for better page pool cache usage. */
		mlx5e_free_rx_mpwqe(rq, wi);

retry:
		alloc_err = rq->xsk_pool ? mlx5e_xsk_alloc_rx_mpwqe(rq, head) :
					   mlx5e_alloc_rx_mpwqe(rq, head);
		if (unlikely(alloc_err)) {
			int reclaim = i - 1;

		if (unlikely(alloc_err))
			if (reclaimed || !reclaim)
				break;

			mlx5e_reclaim_mpwqe_pages(rq, head, reclaim);
			reclaimed = true;

			goto retry;
		}
		head = mlx5_wq_ll_get_wqe_next_ix(wq, head);
	} while (--i);

@@ -1574,7 +1596,7 @@ static inline bool mlx5e_build_rx_skb(struct mlx5_cqe64 *cqe,
				      struct mlx5e_rq *rq,
				      struct sk_buff *skb)
{
	u8 lro_num_seg = be32_to_cpu(cqe->srqn) >> 24;
	u8 lro_num_seg = get_cqe_lro_num_seg(cqe);
	struct mlx5e_rq_stats *stats = rq->stats;
	struct net_device *netdev = rq->netdev;

@@ -2058,6 +2080,15 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w
	u16 linear_hr;
	void *va;

	if (unlikely(cqe_bcnt > rq->hw_mtu)) {
		u8 lro_num_seg = get_cqe_lro_num_seg(cqe);

		if (lro_num_seg <= 1) {
			rq->stats->oversize_pkts_sw_drop++;
			return NULL;
		}
	}

	prog = rcu_dereference(rq->xdp_prog);

	if (prog) {
+5 −0
Original line number Diff line number Diff line
@@ -962,6 +962,11 @@ static inline u16 get_cqe_flow_tag(struct mlx5_cqe64 *cqe)
	return be32_to_cpu(cqe->sop_drop_qpn) & 0xFFF;
}

static inline u8 get_cqe_lro_num_seg(struct mlx5_cqe64 *cqe)
{
	return be32_to_cpu(cqe->srqn) >> 24;
}

#define MLX5_MPWQE_LOG_NUM_STRIDES_EXT_BASE	3
#define MLX5_MPWQE_LOG_NUM_STRIDES_BASE		9
#define MLX5_MPWQE_LOG_NUM_STRIDES_MAX		16