Skip to content

Commit 2c61960

Browse files
sriramykuba-moo
authored andcommitted
igb: Add AF_XDP zero-copy Rx support
Add support for AF_XDP zero-copy receive path. When AF_XDP zero-copy is enabled, the rx buffers are allocated from the xsk buff pool using igb_alloc_rx_buffers_zc(). Use xsk_pool_get_rx_frame_size() to set SRRCTL rx buf size when zero-copy is enabled. Signed-off-by: Sriram Yagnaraman <[email protected]> [Kurt: Port to v6.12 and provide napi_id for xdp_rxq_info_reg(), RCT, remove NETDEV_XDP_ACT_XSK_ZEROCOPY, update NTC handling, READ_ONCE() xsk_pool, likelyfy for XDP_REDIRECT case] Signed-off-by: Kurt Kanzenbach <[email protected]> Acked-by: Maciej Fijalkowski <[email protected]> Tested-by: George Kuruvinakunnel <[email protected]> Signed-off-by: Tony Nguyen <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 0fe7cce commit 2c61960

File tree

3 files changed

+360
-19
lines changed

3 files changed

+360
-19
lines changed

drivers/net/ethernet/intel/igb/igb.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ struct igb_adapter;
8888
#define IGB_XDP_CONSUMED BIT(0)
8989
#define IGB_XDP_TX BIT(1)
9090
#define IGB_XDP_REDIR BIT(2)
91+
#define IGB_XDP_EXIT BIT(3)
9192

9293
struct vf_data_storage {
9394
unsigned char vf_mac_addresses[ETH_ALEN];
@@ -853,6 +854,11 @@ struct xsk_buff_pool *igb_xsk_pool(struct igb_adapter *adapter,
853854
int igb_xsk_pool_setup(struct igb_adapter *adapter,
854855
struct xsk_buff_pool *pool,
855856
u16 qid);
857+
bool igb_alloc_rx_buffers_zc(struct igb_ring *rx_ring,
858+
struct xsk_buff_pool *xsk_pool, u16 count);
859+
void igb_clean_rx_ring_zc(struct igb_ring *rx_ring);
860+
int igb_clean_rx_irq_zc(struct igb_q_vector *q_vector,
861+
struct xsk_buff_pool *xsk_pool, const int budget);
856862
int igb_xsk_wakeup(struct net_device *dev, u32 qid, u32 flags);
857863

858864
#endif /* _IGB_H_ */

drivers/net/ethernet/intel/igb/igb_main.c

Lines changed: 61 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -472,12 +472,17 @@ static void igb_dump(struct igb_adapter *adapter)
472472

473473
for (i = 0; i < rx_ring->count; i++) {
474474
const char *next_desc;
475-
struct igb_rx_buffer *buffer_info;
476-
buffer_info = &rx_ring->rx_buffer_info[i];
475+
dma_addr_t dma = (dma_addr_t)0;
476+
struct igb_rx_buffer *buffer_info = NULL;
477477
rx_desc = IGB_RX_DESC(rx_ring, i);
478478
u0 = (struct my_u0 *)rx_desc;
479479
staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
480480

481+
if (!rx_ring->xsk_pool) {
482+
buffer_info = &rx_ring->rx_buffer_info[i];
483+
dma = buffer_info->dma;
484+
}
485+
481486
if (i == rx_ring->next_to_use)
482487
next_desc = " NTU";
483488
else if (i == rx_ring->next_to_clean)
@@ -497,11 +502,11 @@ static void igb_dump(struct igb_adapter *adapter)
497502
"R ", i,
498503
le64_to_cpu(u0->a),
499504
le64_to_cpu(u0->b),
500-
(u64)buffer_info->dma,
505+
(u64)dma,
501506
next_desc);
502507

503508
if (netif_msg_pktdata(adapter) &&
504-
buffer_info->dma && buffer_info->page) {
509+
buffer_info && dma && buffer_info->page) {
505510
print_hex_dump(KERN_INFO, "",
506511
DUMP_PREFIX_ADDRESS,
507512
16, 1,
@@ -1987,7 +1992,11 @@ static void igb_configure(struct igb_adapter *adapter)
19871992
*/
19881993
for (i = 0; i < adapter->num_rx_queues; i++) {
19891994
struct igb_ring *ring = adapter->rx_ring[i];
1990-
igb_alloc_rx_buffers(ring, igb_desc_unused(ring));
1995+
if (ring->xsk_pool)
1996+
igb_alloc_rx_buffers_zc(ring, ring->xsk_pool,
1997+
igb_desc_unused(ring));
1998+
else
1999+
igb_alloc_rx_buffers(ring, igb_desc_unused(ring));
19912000
}
19922001
}
19932002

@@ -4409,7 +4418,8 @@ int igb_setup_rx_resources(struct igb_ring *rx_ring)
44094418
if (xdp_rxq_info_is_reg(&rx_ring->xdp_rxq))
44104419
xdp_rxq_info_unreg(&rx_ring->xdp_rxq);
44114420
res = xdp_rxq_info_reg(&rx_ring->xdp_rxq, rx_ring->netdev,
4412-
rx_ring->queue_index, 0);
4421+
rx_ring->queue_index,
4422+
rx_ring->q_vector->napi.napi_id);
44134423
if (res < 0) {
44144424
dev_err(dev, "Failed to register xdp_rxq index %u\n",
44154425
rx_ring->queue_index);
@@ -4705,12 +4715,17 @@ void igb_setup_srrctl(struct igb_adapter *adapter, struct igb_ring *ring)
47054715
struct e1000_hw *hw = &adapter->hw;
47064716
int reg_idx = ring->reg_idx;
47074717
u32 srrctl = 0;
4718+
u32 buf_size;
47084719

4709-
srrctl = IGB_RX_HDR_LEN << E1000_SRRCTL_BSIZEHDRSIZE_SHIFT;
4710-
if (ring_uses_large_buffer(ring))
4711-
srrctl |= IGB_RXBUFFER_3072 >> E1000_SRRCTL_BSIZEPKT_SHIFT;
4720+
if (ring->xsk_pool)
4721+
buf_size = xsk_pool_get_rx_frame_size(ring->xsk_pool);
4722+
else if (ring_uses_large_buffer(ring))
4723+
buf_size = IGB_RXBUFFER_3072;
47124724
else
4713-
srrctl |= IGB_RXBUFFER_2048 >> E1000_SRRCTL_BSIZEPKT_SHIFT;
4725+
buf_size = IGB_RXBUFFER_2048;
4726+
4727+
srrctl = IGB_RX_HDR_LEN << E1000_SRRCTL_BSIZEHDRSIZE_SHIFT;
4728+
srrctl |= buf_size >> E1000_SRRCTL_BSIZEPKT_SHIFT;
47144729
srrctl |= E1000_SRRCTL_DESCTYPE_ADV_ONEBUF;
47154730
if (hw->mac.type >= e1000_82580)
47164731
srrctl |= E1000_SRRCTL_TIMESTAMP;
@@ -4742,9 +4757,17 @@ void igb_configure_rx_ring(struct igb_adapter *adapter,
47424757
u32 rxdctl = 0;
47434758

47444759
xdp_rxq_info_unreg_mem_model(&ring->xdp_rxq);
4745-
WARN_ON(xdp_rxq_info_reg_mem_model(&ring->xdp_rxq,
4746-
MEM_TYPE_PAGE_SHARED, NULL));
47474760
WRITE_ONCE(ring->xsk_pool, igb_xsk_pool(adapter, ring));
4761+
if (ring->xsk_pool) {
4762+
WARN_ON(xdp_rxq_info_reg_mem_model(&ring->xdp_rxq,
4763+
MEM_TYPE_XSK_BUFF_POOL,
4764+
NULL));
4765+
xsk_pool_set_rxq_info(ring->xsk_pool, &ring->xdp_rxq);
4766+
} else {
4767+
WARN_ON(xdp_rxq_info_reg_mem_model(&ring->xdp_rxq,
4768+
MEM_TYPE_PAGE_SHARED,
4769+
NULL));
4770+
}
47484771

47494772
/* disable the queue */
47504773
wr32(E1000_RXDCTL(reg_idx), 0);
@@ -4771,9 +4794,12 @@ void igb_configure_rx_ring(struct igb_adapter *adapter,
47714794
rxdctl |= IGB_RX_HTHRESH << 8;
47724795
rxdctl |= IGB_RX_WTHRESH << 16;
47734796

4774-
/* initialize rx_buffer_info */
4775-
memset(ring->rx_buffer_info, 0,
4776-
sizeof(struct igb_rx_buffer) * ring->count);
4797+
if (ring->xsk_pool)
4798+
memset(ring->rx_buffer_info_zc, 0,
4799+
sizeof(*ring->rx_buffer_info_zc) * ring->count);
4800+
else
4801+
memset(ring->rx_buffer_info, 0,
4802+
sizeof(*ring->rx_buffer_info) * ring->count);
47774803

47784804
/* initialize Rx descriptor 0 */
47794805
rx_desc = IGB_RX_DESC(ring, 0);
@@ -4961,8 +4987,13 @@ void igb_free_rx_resources(struct igb_ring *rx_ring)
49614987

49624988
rx_ring->xdp_prog = NULL;
49634989
xdp_rxq_info_unreg(&rx_ring->xdp_rxq);
4964-
vfree(rx_ring->rx_buffer_info);
4965-
rx_ring->rx_buffer_info = NULL;
4990+
if (rx_ring->xsk_pool) {
4991+
vfree(rx_ring->rx_buffer_info_zc);
4992+
rx_ring->rx_buffer_info_zc = NULL;
4993+
} else {
4994+
vfree(rx_ring->rx_buffer_info);
4995+
rx_ring->rx_buffer_info = NULL;
4996+
}
49664997

49674998
/* if not set, then don't free */
49684999
if (!rx_ring->desc)
@@ -5000,6 +5031,11 @@ void igb_clean_rx_ring(struct igb_ring *rx_ring)
50005031
dev_kfree_skb(rx_ring->skb);
50015032
rx_ring->skb = NULL;
50025033

5034+
if (rx_ring->xsk_pool) {
5035+
igb_clean_rx_ring_zc(rx_ring);
5036+
goto skip_for_xsk;
5037+
}
5038+
50035039
/* Free all the Rx ring sk_buffs */
50045040
while (i != rx_ring->next_to_alloc) {
50055041
struct igb_rx_buffer *buffer_info = &rx_ring->rx_buffer_info[i];
@@ -5027,6 +5063,7 @@ void igb_clean_rx_ring(struct igb_ring *rx_ring)
50275063
i = 0;
50285064
}
50295065

5066+
skip_for_xsk:
50305067
rx_ring->next_to_alloc = 0;
50315068
rx_ring->next_to_clean = 0;
50325069
rx_ring->next_to_use = 0;
@@ -8181,6 +8218,7 @@ static int igb_poll(struct napi_struct *napi, int budget)
81818218
struct igb_q_vector *q_vector = container_of(napi,
81828219
struct igb_q_vector,
81838220
napi);
8221+
struct xsk_buff_pool *xsk_pool;
81848222
bool clean_complete = true;
81858223
int work_done = 0;
81868224

@@ -8192,7 +8230,12 @@ static int igb_poll(struct napi_struct *napi, int budget)
81928230
clean_complete = igb_clean_tx_irq(q_vector, budget);
81938231

81948232
if (q_vector->rx.ring) {
8195-
int cleaned = igb_clean_rx_irq(q_vector, budget);
8233+
int cleaned;
8234+
8235+
xsk_pool = READ_ONCE(q_vector->rx.ring->xsk_pool);
8236+
cleaned = xsk_pool ?
8237+
igb_clean_rx_irq_zc(q_vector, xsk_pool, budget) :
8238+
igb_clean_rx_irq(q_vector, budget);
81968239

81978240
work_done += cleaned;
81988241
if (cleaned >= budget)

0 commit comments

Comments
 (0)