Skip to content

Commit 5f4d035

Browse files
committed
Merge branch 'bnxt_en-support-header-page-pool-in-queue-api'
David Wei says: ==================== bnxt_en: support header page pool in queue API Commit 7ed816b ("eth: bnxt: use page pool for head frags") added a separate page pool for header frags. Now, frags are allocated from this header page pool e.g. rxr->tpa_info.data. The queue API did not properly handle rxr->tpa_info and so using the queue API to i.e. reset any queues will result in pages being returned to the incorrect page pool, causing inflight != 0 warnings. Fix this bug by properly allocating/freeing tpa_info and copying/freeing head_pool in the queue API implementation. The 1st patch is a prep patch that refactors helpers out to be used by the implementation patch later. The 2nd patch is a drive-by refactor. Happy to take it out and re-send to net-next if there are any objections. The 3rd patch is the implementation patch that will properly alloc/free rxr->tpa_info. ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 8588c99 + bd649c5 commit 5f4d035

File tree

1 file changed

+129
-76
lines changed
  • drivers/net/ethernet/broadcom/bnxt

1 file changed

+129
-76
lines changed

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

Lines changed: 129 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -3421,15 +3421,11 @@ static void bnxt_free_one_rx_agg_ring(struct bnxt *bp, struct bnxt_rx_ring_info
34213421
}
34223422
}
34233423

3424-
static void bnxt_free_one_rx_ring_skbs(struct bnxt *bp, int ring_nr)
3424+
static void bnxt_free_one_tpa_info_data(struct bnxt *bp,
3425+
struct bnxt_rx_ring_info *rxr)
34253426
{
3426-
struct bnxt_rx_ring_info *rxr = &bp->rx_ring[ring_nr];
3427-
struct bnxt_tpa_idx_map *map;
34283427
int i;
34293428

3430-
if (!rxr->rx_tpa)
3431-
goto skip_rx_tpa_free;
3432-
34333429
for (i = 0; i < bp->max_tpa; i++) {
34343430
struct bnxt_tpa_info *tpa_info = &rxr->rx_tpa[i];
34353431
u8 *data = tpa_info->data;
@@ -3440,6 +3436,17 @@ static void bnxt_free_one_rx_ring_skbs(struct bnxt *bp, int ring_nr)
34403436
tpa_info->data = NULL;
34413437
page_pool_free_va(rxr->head_pool, data, false);
34423438
}
3439+
}
3440+
3441+
static void bnxt_free_one_rx_ring_skbs(struct bnxt *bp,
3442+
struct bnxt_rx_ring_info *rxr)
3443+
{
3444+
struct bnxt_tpa_idx_map *map;
3445+
3446+
if (!rxr->rx_tpa)
3447+
goto skip_rx_tpa_free;
3448+
3449+
bnxt_free_one_tpa_info_data(bp, rxr);
34433450

34443451
skip_rx_tpa_free:
34453452
if (!rxr->rx_buf_ring)
@@ -3467,7 +3474,7 @@ static void bnxt_free_rx_skbs(struct bnxt *bp)
34673474
return;
34683475

34693476
for (i = 0; i < bp->rx_nr_rings; i++)
3470-
bnxt_free_one_rx_ring_skbs(bp, i);
3477+
bnxt_free_one_rx_ring_skbs(bp, &bp->rx_ring[i]);
34713478
}
34723479

34733480
static void bnxt_free_skbs(struct bnxt *bp)
@@ -3608,29 +3615,64 @@ static int bnxt_alloc_ring(struct bnxt *bp, struct bnxt_ring_mem_info *rmem)
36083615
return 0;
36093616
}
36103617

3618+
static void bnxt_free_one_tpa_info(struct bnxt *bp,
3619+
struct bnxt_rx_ring_info *rxr)
3620+
{
3621+
int i;
3622+
3623+
kfree(rxr->rx_tpa_idx_map);
3624+
rxr->rx_tpa_idx_map = NULL;
3625+
if (rxr->rx_tpa) {
3626+
for (i = 0; i < bp->max_tpa; i++) {
3627+
kfree(rxr->rx_tpa[i].agg_arr);
3628+
rxr->rx_tpa[i].agg_arr = NULL;
3629+
}
3630+
}
3631+
kfree(rxr->rx_tpa);
3632+
rxr->rx_tpa = NULL;
3633+
}
3634+
36113635
static void bnxt_free_tpa_info(struct bnxt *bp)
36123636
{
3613-
int i, j;
3637+
int i;
36143638

36153639
for (i = 0; i < bp->rx_nr_rings; i++) {
36163640
struct bnxt_rx_ring_info *rxr = &bp->rx_ring[i];
36173641

3618-
kfree(rxr->rx_tpa_idx_map);
3619-
rxr->rx_tpa_idx_map = NULL;
3620-
if (rxr->rx_tpa) {
3621-
for (j = 0; j < bp->max_tpa; j++) {
3622-
kfree(rxr->rx_tpa[j].agg_arr);
3623-
rxr->rx_tpa[j].agg_arr = NULL;
3624-
}
3625-
}
3626-
kfree(rxr->rx_tpa);
3627-
rxr->rx_tpa = NULL;
3642+
bnxt_free_one_tpa_info(bp, rxr);
3643+
}
3644+
}
3645+
3646+
static int bnxt_alloc_one_tpa_info(struct bnxt *bp,
3647+
struct bnxt_rx_ring_info *rxr)
3648+
{
3649+
struct rx_agg_cmp *agg;
3650+
int i;
3651+
3652+
rxr->rx_tpa = kcalloc(bp->max_tpa, sizeof(struct bnxt_tpa_info),
3653+
GFP_KERNEL);
3654+
if (!rxr->rx_tpa)
3655+
return -ENOMEM;
3656+
3657+
if (!(bp->flags & BNXT_FLAG_CHIP_P5_PLUS))
3658+
return 0;
3659+
for (i = 0; i < bp->max_tpa; i++) {
3660+
agg = kcalloc(MAX_SKB_FRAGS, sizeof(*agg), GFP_KERNEL);
3661+
if (!agg)
3662+
return -ENOMEM;
3663+
rxr->rx_tpa[i].agg_arr = agg;
36283664
}
3665+
rxr->rx_tpa_idx_map = kzalloc(sizeof(*rxr->rx_tpa_idx_map),
3666+
GFP_KERNEL);
3667+
if (!rxr->rx_tpa_idx_map)
3668+
return -ENOMEM;
3669+
3670+
return 0;
36293671
}
36303672

36313673
static int bnxt_alloc_tpa_info(struct bnxt *bp)
36323674
{
3633-
int i, j;
3675+
int i, rc;
36343676

36353677
bp->max_tpa = MAX_TPA;
36363678
if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) {
@@ -3641,25 +3683,10 @@ static int bnxt_alloc_tpa_info(struct bnxt *bp)
36413683

36423684
for (i = 0; i < bp->rx_nr_rings; i++) {
36433685
struct bnxt_rx_ring_info *rxr = &bp->rx_ring[i];
3644-
struct rx_agg_cmp *agg;
3645-
3646-
rxr->rx_tpa = kcalloc(bp->max_tpa, sizeof(struct bnxt_tpa_info),
3647-
GFP_KERNEL);
3648-
if (!rxr->rx_tpa)
3649-
return -ENOMEM;
36503686

3651-
if (!(bp->flags & BNXT_FLAG_CHIP_P5_PLUS))
3652-
continue;
3653-
for (j = 0; j < bp->max_tpa; j++) {
3654-
agg = kcalloc(MAX_SKB_FRAGS, sizeof(*agg), GFP_KERNEL);
3655-
if (!agg)
3656-
return -ENOMEM;
3657-
rxr->rx_tpa[j].agg_arr = agg;
3658-
}
3659-
rxr->rx_tpa_idx_map = kzalloc(sizeof(*rxr->rx_tpa_idx_map),
3660-
GFP_KERNEL);
3661-
if (!rxr->rx_tpa_idx_map)
3662-
return -ENOMEM;
3687+
rc = bnxt_alloc_one_tpa_info(bp, rxr);
3688+
if (rc)
3689+
return rc;
36633690
}
36643691
return 0;
36653692
}
@@ -3683,7 +3710,7 @@ static void bnxt_free_rx_rings(struct bnxt *bp)
36833710
xdp_rxq_info_unreg(&rxr->xdp_rxq);
36843711

36853712
page_pool_destroy(rxr->page_pool);
3686-
if (rxr->page_pool != rxr->head_pool)
3713+
if (bnxt_separate_head_pool())
36873714
page_pool_destroy(rxr->head_pool);
36883715
rxr->page_pool = rxr->head_pool = NULL;
36893716

@@ -3737,6 +3764,19 @@ static int bnxt_alloc_rx_page_pool(struct bnxt *bp,
37373764
return PTR_ERR(pool);
37383765
}
37393766

3767+
static int bnxt_alloc_rx_agg_bmap(struct bnxt *bp, struct bnxt_rx_ring_info *rxr)
3768+
{
3769+
u16 mem_size;
3770+
3771+
rxr->rx_agg_bmap_size = bp->rx_agg_ring_mask + 1;
3772+
mem_size = rxr->rx_agg_bmap_size / 8;
3773+
rxr->rx_agg_bmap = kzalloc(mem_size, GFP_KERNEL);
3774+
if (!rxr->rx_agg_bmap)
3775+
return -ENOMEM;
3776+
3777+
return 0;
3778+
}
3779+
37403780
static int bnxt_alloc_rx_rings(struct bnxt *bp)
37413781
{
37423782
int numa_node = dev_to_node(&bp->pdev->dev);
@@ -3781,19 +3821,15 @@ static int bnxt_alloc_rx_rings(struct bnxt *bp)
37813821

37823822
ring->grp_idx = i;
37833823
if (agg_rings) {
3784-
u16 mem_size;
3785-
37863824
ring = &rxr->rx_agg_ring_struct;
37873825
rc = bnxt_alloc_ring(bp, &ring->ring_mem);
37883826
if (rc)
37893827
return rc;
37903828

37913829
ring->grp_idx = i;
3792-
rxr->rx_agg_bmap_size = bp->rx_agg_ring_mask + 1;
3793-
mem_size = rxr->rx_agg_bmap_size / 8;
3794-
rxr->rx_agg_bmap = kzalloc(mem_size, GFP_KERNEL);
3795-
if (!rxr->rx_agg_bmap)
3796-
return -ENOMEM;
3830+
rc = bnxt_alloc_rx_agg_bmap(bp, rxr);
3831+
if (rc)
3832+
return rc;
37973833
}
37983834
}
37993835
if (bp->flags & BNXT_FLAG_TPA)
@@ -4268,10 +4304,31 @@ static void bnxt_alloc_one_rx_ring_page(struct bnxt *bp,
42684304
rxr->rx_agg_prod = prod;
42694305
}
42704306

4307+
static int bnxt_alloc_one_tpa_info_data(struct bnxt *bp,
4308+
struct bnxt_rx_ring_info *rxr)
4309+
{
4310+
dma_addr_t mapping;
4311+
u8 *data;
4312+
int i;
4313+
4314+
for (i = 0; i < bp->max_tpa; i++) {
4315+
data = __bnxt_alloc_rx_frag(bp, &mapping, rxr,
4316+
GFP_KERNEL);
4317+
if (!data)
4318+
return -ENOMEM;
4319+
4320+
rxr->rx_tpa[i].data = data;
4321+
rxr->rx_tpa[i].data_ptr = data + bp->rx_offset;
4322+
rxr->rx_tpa[i].mapping = mapping;
4323+
}
4324+
4325+
return 0;
4326+
}
4327+
42714328
static int bnxt_alloc_one_rx_ring(struct bnxt *bp, int ring_nr)
42724329
{
42734330
struct bnxt_rx_ring_info *rxr = &bp->rx_ring[ring_nr];
4274-
int i;
4331+
int rc;
42754332

42764333
bnxt_alloc_one_rx_ring_skb(bp, rxr, ring_nr);
42774334

@@ -4281,19 +4338,9 @@ static int bnxt_alloc_one_rx_ring(struct bnxt *bp, int ring_nr)
42814338
bnxt_alloc_one_rx_ring_page(bp, rxr, ring_nr);
42824339

42834340
if (rxr->rx_tpa) {
4284-
dma_addr_t mapping;
4285-
u8 *data;
4286-
4287-
for (i = 0; i < bp->max_tpa; i++) {
4288-
data = __bnxt_alloc_rx_frag(bp, &mapping, rxr,
4289-
GFP_KERNEL);
4290-
if (!data)
4291-
return -ENOMEM;
4292-
4293-
rxr->rx_tpa[i].data = data;
4294-
rxr->rx_tpa[i].data_ptr = data + bp->rx_offset;
4295-
rxr->rx_tpa[i].mapping = mapping;
4296-
}
4341+
rc = bnxt_alloc_one_tpa_info_data(bp, rxr);
4342+
if (rc)
4343+
return rc;
42974344
}
42984345
return 0;
42994346
}
@@ -13663,7 +13710,7 @@ static void bnxt_rx_ring_reset(struct bnxt *bp)
1366313710
bnxt_reset_task(bp, true);
1366413711
break;
1366513712
}
13666-
bnxt_free_one_rx_ring_skbs(bp, i);
13713+
bnxt_free_one_rx_ring_skbs(bp, rxr);
1366713714
rxr->rx_prod = 0;
1366813715
rxr->rx_agg_prod = 0;
1366913716
rxr->rx_sw_agg_prod = 0;
@@ -15293,19 +15340,6 @@ static const struct netdev_stat_ops bnxt_stat_ops = {
1529315340
.get_base_stats = bnxt_get_base_stats,
1529415341
};
1529515342

15296-
static int bnxt_alloc_rx_agg_bmap(struct bnxt *bp, struct bnxt_rx_ring_info *rxr)
15297-
{
15298-
u16 mem_size;
15299-
15300-
rxr->rx_agg_bmap_size = bp->rx_agg_ring_mask + 1;
15301-
mem_size = rxr->rx_agg_bmap_size / 8;
15302-
rxr->rx_agg_bmap = kzalloc(mem_size, GFP_KERNEL);
15303-
if (!rxr->rx_agg_bmap)
15304-
return -ENOMEM;
15305-
15306-
return 0;
15307-
}
15308-
1530915343
static int bnxt_queue_mem_alloc(struct net_device *dev, void *qmem, int idx)
1531015344
{
1531115345
struct bnxt_rx_ring_info *rxr, *clone;
@@ -15354,25 +15388,37 @@ static int bnxt_queue_mem_alloc(struct net_device *dev, void *qmem, int idx)
1535415388
goto err_free_rx_agg_ring;
1535515389
}
1535615390

15391+
if (bp->flags & BNXT_FLAG_TPA) {
15392+
rc = bnxt_alloc_one_tpa_info(bp, clone);
15393+
if (rc)
15394+
goto err_free_tpa_info;
15395+
}
15396+
1535715397
bnxt_init_one_rx_ring_rxbd(bp, clone);
1535815398
bnxt_init_one_rx_agg_ring_rxbd(bp, clone);
1535915399

1536015400
bnxt_alloc_one_rx_ring_skb(bp, clone, idx);
1536115401
if (bp->flags & BNXT_FLAG_AGG_RINGS)
1536215402
bnxt_alloc_one_rx_ring_page(bp, clone, idx);
15403+
if (bp->flags & BNXT_FLAG_TPA)
15404+
bnxt_alloc_one_tpa_info_data(bp, clone);
1536315405

1536415406
return 0;
1536515407

15408+
err_free_tpa_info:
15409+
bnxt_free_one_tpa_info(bp, clone);
1536615410
err_free_rx_agg_ring:
1536715411
bnxt_free_ring(bp, &clone->rx_agg_ring_struct.ring_mem);
1536815412
err_free_rx_ring:
1536915413
bnxt_free_ring(bp, &clone->rx_ring_struct.ring_mem);
1537015414
err_rxq_info_unreg:
1537115415
xdp_rxq_info_unreg(&clone->xdp_rxq);
1537215416
err_page_pool_destroy:
15373-
clone->page_pool->p.napi = NULL;
1537415417
page_pool_destroy(clone->page_pool);
15418+
if (bnxt_separate_head_pool())
15419+
page_pool_destroy(clone->head_pool);
1537515420
clone->page_pool = NULL;
15421+
clone->head_pool = NULL;
1537615422
return rc;
1537715423
}
1537815424

@@ -15382,13 +15428,15 @@ static void bnxt_queue_mem_free(struct net_device *dev, void *qmem)
1538215428
struct bnxt *bp = netdev_priv(dev);
1538315429
struct bnxt_ring_struct *ring;
1538415430

15385-
bnxt_free_one_rx_ring(bp, rxr);
15386-
bnxt_free_one_rx_agg_ring(bp, rxr);
15431+
bnxt_free_one_rx_ring_skbs(bp, rxr);
1538715432

1538815433
xdp_rxq_info_unreg(&rxr->xdp_rxq);
1538915434

1539015435
page_pool_destroy(rxr->page_pool);
15436+
if (bnxt_separate_head_pool())
15437+
page_pool_destroy(rxr->head_pool);
1539115438
rxr->page_pool = NULL;
15439+
rxr->head_pool = NULL;
1539215440

1539315441
ring = &rxr->rx_ring_struct;
1539415442
bnxt_free_ring(bp, &ring->ring_mem);
@@ -15470,7 +15518,10 @@ static int bnxt_queue_start(struct net_device *dev, void *qmem, int idx)
1547015518
rxr->rx_agg_prod = clone->rx_agg_prod;
1547115519
rxr->rx_sw_agg_prod = clone->rx_sw_agg_prod;
1547215520
rxr->rx_next_cons = clone->rx_next_cons;
15521+
rxr->rx_tpa = clone->rx_tpa;
15522+
rxr->rx_tpa_idx_map = clone->rx_tpa_idx_map;
1547315523
rxr->page_pool = clone->page_pool;
15524+
rxr->head_pool = clone->head_pool;
1547415525
rxr->xdp_rxq = clone->xdp_rxq;
1547515526

1547615527
bnxt_copy_rx_ring(bp, rxr, clone);
@@ -15529,6 +15580,8 @@ static int bnxt_queue_stop(struct net_device *dev, void *qmem, int idx)
1552915580
bnxt_hwrm_rx_agg_ring_free(bp, rxr, false);
1553015581
rxr->rx_next_cons = 0;
1553115582
page_pool_disable_direct_recycling(rxr->page_pool);
15583+
if (bnxt_separate_head_pool())
15584+
page_pool_disable_direct_recycling(rxr->head_pool);
1553215585

1553315586
memcpy(qmem, rxr, sizeof(*rxr));
1553415587
bnxt_init_rx_ring_struct(bp, qmem);

0 commit comments

Comments
 (0)