Skip to content

Commit 322b87c

Browse files
CCX-Stingraydavem330
authored andcommitted
bnxt_en: add page_pool support
This removes contention over page allocation for XDP_REDIRECT actions by adding page_pool support per queue for the driver. The performance for XDP_REDIRECT actions scales linearly with the number of cores performing redirect actions when using the page pools instead of the standard page allocator. v2: Fix up the error path from XDP registration, noted by Ilias Apalodimas. Signed-off-by: Andy Gospodarek <[email protected]> Signed-off-by: Michael Chan <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent f18c2b7 commit 322b87c

File tree

4 files changed

+47
-7
lines changed

4 files changed

+47
-7
lines changed

drivers/net/ethernet/broadcom/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ config BNXT
199199
select FW_LOADER
200200
select LIBCRC32C
201201
select NET_DEVLINK
202+
select PAGE_POOL
202203
---help---
203204
This driver supports Broadcom NetXtreme-C/E 10/25/40/50 gigabit
204205
Ethernet cards. To compile this driver as a module, choose M here:

drivers/net/ethernet/broadcom/bnxt/bnxt.c

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
#include <net/pkt_cls.h>
5555
#include <linux/hwmon.h>
5656
#include <linux/hwmon-sysfs.h>
57+
#include <net/page_pool.h>
5758

5859
#include "bnxt_hsi.h"
5960
#include "bnxt.h"
@@ -668,19 +669,20 @@ static void bnxt_tx_int(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts)
668669
}
669670

670671
static struct page *__bnxt_alloc_rx_page(struct bnxt *bp, dma_addr_t *mapping,
672+
struct bnxt_rx_ring_info *rxr,
671673
gfp_t gfp)
672674
{
673675
struct device *dev = &bp->pdev->dev;
674676
struct page *page;
675677

676-
page = alloc_page(gfp);
678+
page = page_pool_dev_alloc_pages(rxr->page_pool);
677679
if (!page)
678680
return NULL;
679681

680682
*mapping = dma_map_page_attrs(dev, page, 0, PAGE_SIZE, bp->rx_dir,
681683
DMA_ATTR_WEAK_ORDERING);
682684
if (dma_mapping_error(dev, *mapping)) {
683-
__free_page(page);
685+
page_pool_recycle_direct(rxr->page_pool, page);
684686
return NULL;
685687
}
686688
*mapping += bp->rx_dma_offset;
@@ -716,7 +718,8 @@ int bnxt_alloc_rx_data(struct bnxt *bp, struct bnxt_rx_ring_info *rxr,
716718
dma_addr_t mapping;
717719

718720
if (BNXT_RX_PAGE_MODE(bp)) {
719-
struct page *page = __bnxt_alloc_rx_page(bp, &mapping, gfp);
721+
struct page *page =
722+
__bnxt_alloc_rx_page(bp, &mapping, rxr, gfp);
720723

721724
if (!page)
722725
return -ENOMEM;
@@ -2360,7 +2363,7 @@ static void bnxt_free_rx_skbs(struct bnxt *bp)
23602363
dma_unmap_page_attrs(&pdev->dev, mapping,
23612364
PAGE_SIZE, bp->rx_dir,
23622365
DMA_ATTR_WEAK_ORDERING);
2363-
__free_page(data);
2366+
page_pool_recycle_direct(rxr->page_pool, data);
23642367
} else {
23652368
dma_unmap_single_attrs(&pdev->dev, mapping,
23662369
bp->rx_buf_use_size,
@@ -2497,6 +2500,8 @@ static void bnxt_free_rx_rings(struct bnxt *bp)
24972500
if (xdp_rxq_info_is_reg(&rxr->xdp_rxq))
24982501
xdp_rxq_info_unreg(&rxr->xdp_rxq);
24992502

2503+
rxr->page_pool = NULL;
2504+
25002505
kfree(rxr->rx_tpa);
25012506
rxr->rx_tpa = NULL;
25022507

@@ -2511,6 +2516,26 @@ static void bnxt_free_rx_rings(struct bnxt *bp)
25112516
}
25122517
}
25132518

2519+
static int bnxt_alloc_rx_page_pool(struct bnxt *bp,
2520+
struct bnxt_rx_ring_info *rxr)
2521+
{
2522+
struct page_pool_params pp = { 0 };
2523+
2524+
pp.pool_size = bp->rx_ring_size;
2525+
pp.nid = dev_to_node(&bp->pdev->dev);
2526+
pp.dev = &bp->pdev->dev;
2527+
pp.dma_dir = DMA_BIDIRECTIONAL;
2528+
2529+
rxr->page_pool = page_pool_create(&pp);
2530+
if (IS_ERR(rxr->page_pool)) {
2531+
int err = PTR_ERR(rxr->page_pool);
2532+
2533+
rxr->page_pool = NULL;
2534+
return err;
2535+
}
2536+
return 0;
2537+
}
2538+
25142539
static int bnxt_alloc_rx_rings(struct bnxt *bp)
25152540
{
25162541
int i, rc, agg_rings = 0, tpa_rings = 0;
@@ -2530,14 +2555,24 @@ static int bnxt_alloc_rx_rings(struct bnxt *bp)
25302555

25312556
ring = &rxr->rx_ring_struct;
25322557

2558+
rc = bnxt_alloc_rx_page_pool(bp, rxr);
2559+
if (rc)
2560+
return rc;
2561+
25332562
rc = xdp_rxq_info_reg(&rxr->xdp_rxq, bp->dev, i);
2534-
if (rc < 0)
2563+
if (rc < 0) {
2564+
page_pool_free(rxr->page_pool);
2565+
rxr->page_pool = NULL;
25352566
return rc;
2567+
}
25362568

25372569
rc = xdp_rxq_info_reg_mem_model(&rxr->xdp_rxq,
2538-
MEM_TYPE_PAGE_SHARED, NULL);
2570+
MEM_TYPE_PAGE_POOL,
2571+
rxr->page_pool);
25392572
if (rc) {
25402573
xdp_rxq_info_unreg(&rxr->xdp_rxq);
2574+
page_pool_free(rxr->page_pool);
2575+
rxr->page_pool = NULL;
25412576
return rc;
25422577
}
25432578

drivers/net/ethernet/broadcom/bnxt/bnxt.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#include <net/xdp.h>
2727
#include <linux/dim.h>
2828

29+
struct page_pool;
30+
2931
struct tx_bd {
3032
__le32 tx_bd_len_flags_type;
3133
#define TX_BD_TYPE (0x3f << 0)
@@ -799,6 +801,7 @@ struct bnxt_rx_ring_info {
799801
struct bnxt_ring_struct rx_ring_struct;
800802
struct bnxt_ring_struct rx_agg_ring_struct;
801803
struct xdp_rxq_info xdp_rxq;
804+
struct page_pool *page_pool;
802805
};
803806

804807
struct bnxt_cp_ring_info {

drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <linux/bpf.h>
1616
#include <linux/bpf_trace.h>
1717
#include <linux/filter.h>
18+
#include <net/page_pool.h>
1819
#include "bnxt_hsi.h"
1920
#include "bnxt.h"
2021
#include "bnxt_xdp.h"
@@ -191,7 +192,7 @@ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
191192

192193
if (xdp_do_redirect(bp->dev, &xdp, xdp_prog)) {
193194
trace_xdp_exception(bp->dev, xdp_prog, act);
194-
__free_page(page);
195+
page_pool_recycle_direct(rxr->page_pool, page);
195196
return true;
196197
}
197198

0 commit comments

Comments
 (0)