Commit 505b1a88 authored by David Arinzon's avatar David Arinzon Committed by Jakub Kicinski
Browse files

net: ena: Fix xdp drops handling due to multibuf packets



Current xdp code drops packets larger than ENA_XDP_MAX_MTU.
This is an incorrect condition since the problem is not the
size of the packet, rather the number of buffers it contains.

This commit:

1. Identifies and drops XDP multi-buffer packets at the
   beginning of the function.
2. Increases the xdp drop statistic when this drop occurs.
3. Adds a one-time print that such drops are happening to
   give better indication to the user.

Fixes: 838c93dc ("net: ena: implement XDP drop support")
Signed-off-by: default avatarArthur Kiyanovski <akiyano@amazon.com>
Signed-off-by: default avatarDavid Arinzon <darinzon@amazon.com>
Link: https://lore.kernel.org/r/20231211062801.27891-3-darinzon@amazon.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 41db6f99
Loading
Loading
Loading
Loading
+10 −7
Original line number Diff line number Diff line
@@ -1672,20 +1672,23 @@ static void ena_set_rx_hash(struct ena_ring *rx_ring,
	}
}

static int ena_xdp_handle_buff(struct ena_ring *rx_ring, struct xdp_buff *xdp)
static int ena_xdp_handle_buff(struct ena_ring *rx_ring, struct xdp_buff *xdp, u16 num_descs)
{
	struct ena_rx_buffer *rx_info;
	int ret;

	/* XDP multi-buffer packets not supported */
	if (unlikely(num_descs > 1)) {
		netdev_err_once(rx_ring->adapter->netdev,
				"xdp: dropped unsupported multi-buffer packets\n");
		ena_increase_stat(&rx_ring->rx_stats.xdp_drop, 1, &rx_ring->syncp);
		return ENA_XDP_DROP;
	}

	rx_info = &rx_ring->rx_buffer_info[rx_ring->ena_bufs[0].req_id];
	xdp_prepare_buff(xdp, page_address(rx_info->page),
			 rx_info->buf_offset,
			 rx_ring->ena_bufs[0].len, false);
	/* If for some reason we received a bigger packet than
	 * we expect, then we simply drop it
	 */
	if (unlikely(rx_ring->ena_bufs[0].len > ENA_XDP_MAX_MTU))
		return ENA_XDP_DROP;

	ret = ena_xdp_execute(rx_ring, xdp);

@@ -1754,7 +1757,7 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi,
			  ena_rx_ctx.l4_proto, ena_rx_ctx.hash);

		if (ena_xdp_present_ring(rx_ring))
			xdp_verdict = ena_xdp_handle_buff(rx_ring, &xdp);
			xdp_verdict = ena_xdp_handle_buff(rx_ring, &xdp, ena_rx_ctx.descs);

		/* allocate skb and fill it */
		if (xdp_verdict == ENA_XDP_PASS)