]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
bnxt_en: Use page frag RX buffers for better software GRO performance
authorJakub Kicinski <kuba@kernel.org>
Mon, 27 Dec 2021 08:00:32 +0000 (03:00 -0500)
committerDavid S. Miller <davem@davemloft.net>
Mon, 27 Dec 2021 12:00:28 +0000 (12:00 +0000)
If NETIF_F_GRO_HW is disabled, the existing driver code uses kmalloc'ed
data for RX buffers.  This causes inefficient SW GRO performance
because the GRO data is merged using the less efficient frag_list.
Use netdev_alloc_frag() and friends instead so that GRO data can be
merged into skb_shinfo(skb)->frags for better performance.

[Use skb_free_frag() - Vikas Gupta]

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Reviewed-by: Andy Gospodarek <gospo@broadcom.com>
Signed-off-by: Vikas Gupta <vikas.gupta@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/bnxt/bnxt.c

index ea5b072ba292d98a8cb6720e9ad5db2fe65921df..4d7ea62e24fb925f577de1492aaa2ea6a25a9bf6 100644 (file)
@@ -741,13 +741,16 @@ static struct page *__bnxt_alloc_rx_page(struct bnxt *bp, dma_addr_t *mapping,
        return page;
 }
 
-static inline u8 *__bnxt_alloc_rx_data(struct bnxt *bp, dma_addr_t *mapping,
+static inline u8 *__bnxt_alloc_rx_frag(struct bnxt *bp, dma_addr_t *mapping,
                                       gfp_t gfp)
 {
        u8 *data;
        struct pci_dev *pdev = bp->pdev;
 
-       data = kmalloc(bp->rx_buf_size, gfp);
+       if (gfp == GFP_ATOMIC)
+               data = napi_alloc_frag(bp->rx_buf_size);
+       else
+               data = netdev_alloc_frag(bp->rx_buf_size);
        if (!data)
                return NULL;
 
@@ -756,7 +759,7 @@ static inline u8 *__bnxt_alloc_rx_data(struct bnxt *bp, dma_addr_t *mapping,
                                        DMA_ATTR_WEAK_ORDERING);
 
        if (dma_mapping_error(&pdev->dev, *mapping)) {
-               kfree(data);
+               skb_free_frag(data);
                data = NULL;
        }
        return data;
@@ -779,7 +782,7 @@ int bnxt_alloc_rx_data(struct bnxt *bp, struct bnxt_rx_ring_info *rxr,
                rx_buf->data = page;
                rx_buf->data_ptr = page_address(page) + bp->rx_offset;
        } else {
-               u8 *data = __bnxt_alloc_rx_data(bp, &mapping, gfp);
+               u8 *data = __bnxt_alloc_rx_frag(bp, &mapping, gfp);
 
                if (!data)
                        return -ENOMEM;
@@ -1021,11 +1024,11 @@ static struct sk_buff *bnxt_rx_skb(struct bnxt *bp,
                return NULL;
        }
 
-       skb = build_skb(data, 0);
+       skb = build_skb(data, bp->rx_buf_size);
        dma_unmap_single_attrs(&bp->pdev->dev, dma_addr, bp->rx_buf_use_size,
                               bp->rx_dir, DMA_ATTR_WEAK_ORDERING);
        if (!skb) {
-               kfree(data);
+               skb_free_frag(data);
                return NULL;
        }
 
@@ -1613,7 +1616,7 @@ static inline struct sk_buff *bnxt_tpa_end(struct bnxt *bp,
                u8 *new_data;
                dma_addr_t new_mapping;
 
-               new_data = __bnxt_alloc_rx_data(bp, &new_mapping, GFP_ATOMIC);
+               new_data = __bnxt_alloc_rx_frag(bp, &new_mapping, GFP_ATOMIC);
                if (!new_data) {
                        bnxt_abort_tpa(cpr, idx, agg_bufs);
                        cpr->sw_stats.rx.rx_oom_discards += 1;
@@ -1624,13 +1627,13 @@ static inline struct sk_buff *bnxt_tpa_end(struct bnxt *bp,
                tpa_info->data_ptr = new_data + bp->rx_offset;
                tpa_info->mapping = new_mapping;
 
-               skb = build_skb(data, 0);
+               skb = build_skb(data, bp->rx_buf_size);
                dma_unmap_single_attrs(&bp->pdev->dev, mapping,
                                       bp->rx_buf_use_size, bp->rx_dir,
                                       DMA_ATTR_WEAK_ORDERING);
 
                if (!skb) {
-                       kfree(data);
+                       skb_free_frag(data);
                        bnxt_abort_tpa(cpr, idx, agg_bufs);
                        cpr->sw_stats.rx.rx_oom_discards += 1;
                        return NULL;
@@ -2796,7 +2799,7 @@ static void bnxt_free_one_rx_ring_skbs(struct bnxt *bp, int ring_nr)
 
                tpa_info->data = NULL;
 
-               kfree(data);
+               skb_free_frag(data);
        }
 
 skip_rx_tpa_free:
@@ -2822,7 +2825,7 @@ skip_rx_tpa_free:
                        dma_unmap_single_attrs(&pdev->dev, mapping,
                                               bp->rx_buf_use_size, bp->rx_dir,
                                               DMA_ATTR_WEAK_ORDERING);
-                       kfree(data);
+                       skb_free_frag(data);
                }
        }
 
@@ -3526,7 +3529,7 @@ static int bnxt_alloc_one_rx_ring(struct bnxt *bp, int ring_nr)
                u8 *data;
 
                for (i = 0; i < bp->max_tpa; i++) {
-                       data = __bnxt_alloc_rx_data(bp, &mapping, GFP_KERNEL);
+                       data = __bnxt_alloc_rx_frag(bp, &mapping, GFP_KERNEL);
                        if (!data)
                                return -ENOMEM;