[PATCH 19/34] net: mana: Enable RX path to handle various MTU sizes
authorHaiyang Zhang <haiyangz@microsoft.com>
Wed, 12 Apr 2023 21:16:02 +0000 (14:16 -0700)
committerSalvatore Bonaccorso <carnil@debian.org>
Thu, 2 Jan 2025 13:31:22 +0000 (14:31 +0100)
Update RX data path to allocate and use RX queue DMA buffers with
proper size based on potentially various MTU sizes.

Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 2fbbd712baf1c60996554326728bbdbef5616e12)
Signed-off-by: Bastian Blank <waldi@debian.org>
Gbp-Pq: Topic features/all/ethernet-microsoft
Gbp-Pq: Name 0019-net-mana-Enable-RX-path-to-handle-various-MTU-sizes.patch

drivers/net/ethernet/microsoft/mana/mana_en.c
include/net/mana/mana.h

index 7b957573e1553f140f4a1084354c82ba03e007f2..966baac0d3d50afd6b36c7d5e9577feb653e2675 100644 (file)
@@ -1190,10 +1190,10 @@ static void mana_post_pkt_rxq(struct mana_rxq *rxq)
        WARN_ON_ONCE(recv_buf_oob->wqe_inf.wqe_size_in_bu != 1);
 }
 
-static struct sk_buff *mana_build_skb(void *buf_va, uint pkt_len,
-                                     struct xdp_buff *xdp)
+static struct sk_buff *mana_build_skb(struct mana_rxq *rxq, void *buf_va,
+                                     uint pkt_len, struct xdp_buff *xdp)
 {
-       struct sk_buff *skb = napi_build_skb(buf_va, PAGE_SIZE);
+       struct sk_buff *skb = napi_build_skb(buf_va, rxq->alloc_size);
 
        if (!skb)
                return NULL;
@@ -1201,11 +1201,12 @@ static struct sk_buff *mana_build_skb(void *buf_va, uint pkt_len,
        if (xdp->data_hard_start) {
                skb_reserve(skb, xdp->data - xdp->data_hard_start);
                skb_put(skb, xdp->data_end - xdp->data);
-       } else {
-               skb_reserve(skb, XDP_PACKET_HEADROOM);
-               skb_put(skb, pkt_len);
+               return skb;
        }
 
+       skb_reserve(skb, rxq->headroom);
+       skb_put(skb, pkt_len);
+
        return skb;
 }
 
@@ -1238,7 +1239,7 @@ static void mana_rx_skb(void *buf_va, struct mana_rxcomp_oob *cqe,
        if (act != XDP_PASS && act != XDP_TX)
                goto drop_xdp;
 
-       skb = mana_build_skb(buf_va, pkt_len, &xdp);
+       skb = mana_build_skb(rxq, buf_va, pkt_len, &xdp);
 
        if (!skb)
                goto drop;
@@ -1306,6 +1307,14 @@ static void *mana_get_rxfrag(struct mana_rxq *rxq, struct device *dev,
        if (rxq->xdp_save_va) {
                va = rxq->xdp_save_va;
                rxq->xdp_save_va = NULL;
+       } else if (rxq->alloc_size > PAGE_SIZE) {
+               if (is_napi)
+                       va = napi_alloc_frag(rxq->alloc_size);
+               else
+                       va = netdev_alloc_frag(rxq->alloc_size);
+
+               if (!va)
+                       return NULL;
        } else {
                page = dev_alloc_page();
                if (!page)
@@ -1314,7 +1323,7 @@ static void *mana_get_rxfrag(struct mana_rxq *rxq, struct device *dev,
                va = page_to_virt(page);
        }
 
-       *da = dma_map_single(dev, va + XDP_PACKET_HEADROOM, rxq->datasize,
+       *da = dma_map_single(dev, va + rxq->headroom, rxq->datasize,
                             DMA_FROM_DEVICE);
 
        if (dma_mapping_error(dev, *da)) {
@@ -1747,7 +1756,7 @@ static int mana_alloc_rx_wqe(struct mana_port_context *apc,
        u32 buf_idx;
        int ret;
 
-       WARN_ON(rxq->datasize == 0 || rxq->datasize > PAGE_SIZE);
+       WARN_ON(rxq->datasize == 0);
 
        *rxq_size = 0;
        *cq_size = 0;
@@ -1803,6 +1812,7 @@ static struct mana_rxq *mana_create_rxq(struct mana_port_context *apc,
        struct gdma_dev *gd = apc->ac->gdma_dev;
        struct mana_obj_spec wq_spec;
        struct mana_obj_spec cq_spec;
+       unsigned int mtu = ndev->mtu;
        struct gdma_queue_spec spec;
        struct mana_cq *cq = NULL;
        struct gdma_context *gc;
@@ -1822,7 +1832,15 @@ static struct mana_rxq *mana_create_rxq(struct mana_port_context *apc,
        rxq->rxq_idx = rxq_idx;
        rxq->rxobj = INVALID_MANA_HANDLE;
 
-       rxq->datasize = ALIGN(ETH_FRAME_LEN, 64);
+       rxq->datasize = ALIGN(mtu + ETH_HLEN, 64);
+
+       if (mtu > MANA_XDP_MTU_MAX) {
+               rxq->alloc_size = mtu + MANA_RXBUF_PAD;
+               rxq->headroom = 0;
+       } else {
+               rxq->alloc_size = mtu + MANA_RXBUF_PAD + XDP_PACKET_HEADROOM;
+               rxq->headroom = XDP_PACKET_HEADROOM;
+       }
 
        err = mana_alloc_rx_wqe(apc, rxq, &rq_size, &cq_size);
        if (err)
index e4a953c6c73a03e927655fdaf936a6e567434bc3..c30a1390e78b64cb9fa67ff0afb18c916e93040f 100644 (file)
@@ -294,6 +294,11 @@ struct mana_recv_buf_oob {
        struct gdma_posted_wqe_info wqe_inf;
 };
 
+#define MANA_RXBUF_PAD (SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) \
+                       + ETH_HLEN)
+
+#define MANA_XDP_MTU_MAX (PAGE_SIZE - MANA_RXBUF_PAD - XDP_PACKET_HEADROOM)
+
 struct mana_rxq {
        struct gdma_queue *gdma_rq;
        /* Cache the gdma receive queue id */
@@ -303,6 +308,8 @@ struct mana_rxq {
        u32 rxq_idx;
 
        u32 datasize;
+       u32 alloc_size;
+       u32 headroom;
 
        mana_handle_t rxobj;