Skip to content

Commit 8f497dc

Browse files
walking-machinekuba-moo
authored andcommitted
i40e: fix registering XDP RxQ info
Current way of handling XDP RxQ info in i40e has a problem, where frag_size is not updated when xsk_buff_pool is detached or when MTU is changed, this leads to growing tail always failing for multi-buffer packets. Couple XDP RxQ info registering with buffer allocations and unregistering with cleaning the ring. Fixes: a045d2f ("i40e: set xdp_rxq_info::frag_size") Reviewed-by: Aleksandr Loktionov <[email protected]> Signed-off-by: Larysa Zaremba <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent e142dc4 commit 8f497dc

2 files changed

Lines changed: 22 additions & 17 deletions

File tree

drivers/net/ethernet/intel/i40e/i40e_main.c

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3583,18 +3583,8 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring)
35833583
if (ring->vsi->type != I40E_VSI_MAIN)
35843584
goto skip;
35853585

3586-
if (!xdp_rxq_info_is_reg(&ring->xdp_rxq)) {
3587-
err = __xdp_rxq_info_reg(&ring->xdp_rxq, ring->netdev,
3588-
ring->queue_index,
3589-
ring->q_vector->napi.napi_id,
3590-
ring->rx_buf_len);
3591-
if (err)
3592-
return err;
3593-
}
3594-
35953586
ring->xsk_pool = i40e_xsk_pool(ring);
35963587
if (ring->xsk_pool) {
3597-
xdp_rxq_info_unreg(&ring->xdp_rxq);
35983588
ring->rx_buf_len = xsk_pool_get_rx_frame_size(ring->xsk_pool);
35993589
err = __xdp_rxq_info_reg(&ring->xdp_rxq, ring->netdev,
36003590
ring->queue_index,
@@ -3606,17 +3596,23 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring)
36063596
MEM_TYPE_XSK_BUFF_POOL,
36073597
NULL);
36083598
if (err)
3609-
return err;
3599+
goto unreg_xdp;
36103600
dev_info(&vsi->back->pdev->dev,
36113601
"Registered XDP mem model MEM_TYPE_XSK_BUFF_POOL on Rx ring %d\n",
36123602
ring->queue_index);
36133603

36143604
} else {
3605+
err = __xdp_rxq_info_reg(&ring->xdp_rxq, ring->netdev,
3606+
ring->queue_index,
3607+
ring->q_vector->napi.napi_id,
3608+
ring->rx_buf_len);
3609+
if (err)
3610+
return err;
36153611
err = xdp_rxq_info_reg_mem_model(&ring->xdp_rxq,
36163612
MEM_TYPE_PAGE_SHARED,
36173613
NULL);
36183614
if (err)
3619-
return err;
3615+
goto unreg_xdp;
36203616
}
36213617

36223618
skip:
@@ -3654,7 +3650,8 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring)
36543650
dev_info(&vsi->back->pdev->dev,
36553651
"Failed to clear LAN Rx queue context on Rx ring %d (pf_q %d), error: %d\n",
36563652
ring->queue_index, pf_q, err);
3657-
return -ENOMEM;
3653+
err = -ENOMEM;
3654+
goto unreg_xdp;
36583655
}
36593656

36603657
/* set the context in the HMC */
@@ -3663,15 +3660,17 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring)
36633660
dev_info(&vsi->back->pdev->dev,
36643661
"Failed to set LAN Rx queue context on Rx ring %d (pf_q %d), error: %d\n",
36653662
ring->queue_index, pf_q, err);
3666-
return -ENOMEM;
3663+
err = -ENOMEM;
3664+
goto unreg_xdp;
36673665
}
36683666

36693667
/* configure Rx buffer alignment */
36703668
if (!vsi->netdev || test_bit(I40E_FLAG_LEGACY_RX_ENA, vsi->back->flags)) {
36713669
if (I40E_2K_TOO_SMALL_WITH_PADDING) {
36723670
dev_info(&vsi->back->pdev->dev,
36733671
"2k Rx buffer is too small to fit standard MTU and skb_shared_info\n");
3674-
return -EOPNOTSUPP;
3672+
err = -EOPNOTSUPP;
3673+
goto unreg_xdp;
36753674
}
36763675
clear_ring_build_skb_enabled(ring);
36773676
} else {
@@ -3701,6 +3700,11 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring)
37013700
}
37023701

37033702
return 0;
3703+
unreg_xdp:
3704+
if (ring->vsi->type == I40E_VSI_MAIN)
3705+
xdp_rxq_info_unreg(&ring->xdp_rxq);
3706+
3707+
return err;
37043708
}
37053709

37063710
/**

drivers/net/ethernet/intel/i40e/i40e_txrx.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1470,6 +1470,9 @@ void i40e_clean_rx_ring(struct i40e_ring *rx_ring)
14701470
if (!rx_ring->rx_bi)
14711471
return;
14721472

1473+
if (xdp_rxq_info_is_reg(&rx_ring->xdp_rxq))
1474+
xdp_rxq_info_unreg(&rx_ring->xdp_rxq);
1475+
14731476
if (rx_ring->xsk_pool) {
14741477
i40e_xsk_clean_rx_ring(rx_ring);
14751478
goto skip_free;
@@ -1527,8 +1530,6 @@ void i40e_clean_rx_ring(struct i40e_ring *rx_ring)
15271530
void i40e_free_rx_resources(struct i40e_ring *rx_ring)
15281531
{
15291532
i40e_clean_rx_ring(rx_ring);
1530-
if (rx_ring->vsi->type == I40E_VSI_MAIN)
1531-
xdp_rxq_info_unreg(&rx_ring->xdp_rxq);
15321533
rx_ring->xdp_prog = NULL;
15331534
kfree(rx_ring->rx_bi);
15341535
rx_ring->rx_bi = NULL;

0 commit comments

Comments
 (0)