net: ena: Fix xdp drops handling due to multibuf packets
authorDavid Arinzon <darinzon@amazon.com>
Mon, 11 Dec 2023 06:27:59 +0000 (06:27 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 20 Dec 2023 16:01:49 +0000 (17:01 +0100)
[ Upstream commit 505b1a88d311ff6f8c44a34f94e3be21745cce6f ]

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: 838c93dc5449 ("net: ena: implement XDP drop support")
Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
Signed-off-by: David Arinzon <darinzon@amazon.com>
Link: https://lore.kernel.org/r/20231211062801.27891-3-darinzon@amazon.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/ethernet/amazon/ena/ena_netdev.c

index 098025d292473bef5a2cffc232fa0c80c3c50982..b638e1d3d151a95a9be1bb2dab770a00ba36706a 100644 (file)
@@ -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)