Skip to content

Commit 5cc5924

Browse files
author
Alexei Starovoitov
committed
Merge branch 'xdp-grow-tail'
Jesper Dangaard Brouer says: ==================== V4: - Fixup checkpatch.pl issues - Collected more ACKs V3: - Fix issue on virtio_net patch spotted by Jason Wang - Adjust name for variable in mlx5 patch - Collected more ACKs V2: - Fix bug in mlx5 for XDP_PASS case - Collected nitpicks and ACKs from mailing list V1: - Fix bug in dpaa2 XDP have evolved to support several frame sizes, but xdp_buff was not updated with this information. This have caused the side-effect that XDP frame data hard end is unknown. This have limited the BPF-helper bpf_xdp_adjust_tail to only shrink the packet. This patchset address this and add packet tail extend/grow. The purpose of the patchset is ALSO to reserve a memory area that can be used for storing extra information, specifically for extending XDP with multi-buffer support. One proposal is to use same layout as skb_shared_info, which is why this area is currently 320 bytes. When converting xdp_frame to SKB (veth and cpumap), the full tailroom area can now be used and SKB truesize is now correct. For most drivers this result in a much larger tailroom in SKB "head" data area. The network stack can now take advantage of this when doing SKB coalescing. Thus, a good driver test is to use xdp_redirect_cpu from samples/bpf/ and do some TCP stream testing. Use-cases for tail grow/extend: (1) IPsec / XFRM needs a tail extend[1][2]. (2) DNS-cache responses in XDP. (3) HAProxy ALOHA would need it to convert to XDP. (4) Add tail info e.g. timestamp and collect via tcpdump [1] http://vger.kernel.org/netconf2019_files/xfrm_xdp.pdf [2] http://vger.kernel.org/netconf2019.html Examples on howto access the tail area of an XDP packet is shown in the XDP-tutorial example[3]. [3] https://github.com/xdp-project/xdp-tutorial/blob/master/experiment01-tailgrow/ ==================== Signed-off-by: Alexei Starovoitov <[email protected]>
2 parents d00f26b + 7ae2e00 commit 5cc5924

File tree

43 files changed

+451
-115
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+451
-115
lines changed

drivers/net/ethernet/amazon/ena/ena_netdev.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1606,6 +1606,7 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi,
16061606
"%s qid %d\n", __func__, rx_ring->qid);
16071607
res_budget = budget;
16081608
xdp.rxq = &rx_ring->xdp_rxq;
1609+
xdp.frame_sz = ENA_PAGE_SIZE;
16091610

16101611
do {
16111612
xdp_verdict = XDP_PASS;

drivers/net/ethernet/amazon/ena/ena_netdev.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,9 @@
151151
* The buffer size we share with the device is defined to be ENA_PAGE_SIZE
152152
*/
153153

154-
#define ENA_XDP_MAX_MTU (ENA_PAGE_SIZE - ETH_HLEN - ETH_FCS_LEN - \
155-
VLAN_HLEN - XDP_PACKET_HEADROOM)
154+
#define ENA_XDP_MAX_MTU (ENA_PAGE_SIZE - ETH_HLEN - ETH_FCS_LEN - \
155+
VLAN_HLEN - XDP_PACKET_HEADROOM - \
156+
SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
156157

157158
#define ENA_IS_XDP_INDEX(adapter, index) (((index) >= (adapter)->xdp_first_ring) && \
158159
((index) < (adapter)->xdp_first_ring + (adapter)->xdp_num_queues))

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
138138
xdp_set_data_meta_invalid(&xdp);
139139
xdp.data_end = *data_ptr + *len;
140140
xdp.rxq = &rxr->xdp_rxq;
141+
xdp.frame_sz = PAGE_SIZE; /* BNXT_RX_PAGE_MODE(bp) when XDP enabled */
141142
orig_data = xdp.data;
142143

143144
rcu_read_lock();

drivers/net/ethernet/cavium/thunder/nicvf_main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,7 @@ static inline bool nicvf_xdp_rx(struct nicvf *nic, struct bpf_prog *prog,
552552
xdp_set_data_meta_invalid(&xdp);
553553
xdp.data_end = xdp.data + len;
554554
xdp.rxq = &rq->xdp_rxq;
555+
xdp.frame_sz = RCV_FRAG_LEN + XDP_PACKET_HEADROOM;
555556
orig_data = xdp.data;
556557

557558
rcu_read_lock();

drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,9 @@ static u32 run_xdp(struct dpaa2_eth_priv *priv,
331331
xdp_set_data_meta_invalid(&xdp);
332332
xdp.rxq = &ch->xdp_rxq;
333333

334+
xdp.frame_sz = DPAA2_ETH_RX_BUF_RAW_SIZE -
335+
(dpaa2_fd_get_offset(fd) - XDP_PACKET_HEADROOM);
336+
334337
xdp_act = bpf_prog_run_xdp(xdp_prog, &xdp);
335338

336339
/* xdp.data pointer may have changed */
@@ -366,7 +369,11 @@ static u32 run_xdp(struct dpaa2_eth_priv *priv,
366369
dma_unmap_page(priv->net_dev->dev.parent, addr,
367370
DPAA2_ETH_RX_BUF_SIZE, DMA_BIDIRECTIONAL);
368371
ch->buf_count--;
372+
373+
/* Allow redirect use of full headroom */
369374
xdp.data_hard_start = vaddr;
375+
xdp.frame_sz = DPAA2_ETH_RX_BUF_RAW_SIZE;
376+
370377
err = xdp_do_redirect(priv->net_dev, &xdp, xdp_prog);
371378
if (unlikely(err))
372379
ch->stats.xdp_drop++;

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

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1507,6 +1507,22 @@ static inline unsigned int i40e_rx_offset(struct i40e_ring *rx_ring)
15071507
return ring_uses_build_skb(rx_ring) ? I40E_SKB_PAD : 0;
15081508
}
15091509

1510+
static unsigned int i40e_rx_frame_truesize(struct i40e_ring *rx_ring,
1511+
unsigned int size)
1512+
{
1513+
unsigned int truesize;
1514+
1515+
#if (PAGE_SIZE < 8192)
1516+
truesize = i40e_rx_pg_size(rx_ring) / 2; /* Must be power-of-2 */
1517+
#else
1518+
truesize = i40e_rx_offset(rx_ring) ?
1519+
SKB_DATA_ALIGN(size + i40e_rx_offset(rx_ring)) +
1520+
SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) :
1521+
SKB_DATA_ALIGN(size);
1522+
#endif
1523+
return truesize;
1524+
}
1525+
15101526
/**
15111527
* i40e_alloc_mapped_page - recycle or make a new page
15121528
* @rx_ring: ring to use
@@ -2246,13 +2262,11 @@ static void i40e_rx_buffer_flip(struct i40e_ring *rx_ring,
22462262
struct i40e_rx_buffer *rx_buffer,
22472263
unsigned int size)
22482264
{
2249-
#if (PAGE_SIZE < 8192)
2250-
unsigned int truesize = i40e_rx_pg_size(rx_ring) / 2;
2265+
unsigned int truesize = i40e_rx_frame_truesize(rx_ring, size);
22512266

2267+
#if (PAGE_SIZE < 8192)
22522268
rx_buffer->page_offset ^= truesize;
22532269
#else
2254-
unsigned int truesize = SKB_DATA_ALIGN(i40e_rx_offset(rx_ring) + size);
2255-
22562270
rx_buffer->page_offset += truesize;
22572271
#endif
22582272
}
@@ -2335,6 +2349,9 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget)
23352349
bool failure = false;
23362350
struct xdp_buff xdp;
23372351

2352+
#if (PAGE_SIZE < 8192)
2353+
xdp.frame_sz = i40e_rx_frame_truesize(rx_ring, 0);
2354+
#endif
23382355
xdp.rxq = &rx_ring->xdp_rxq;
23392356

23402357
while (likely(total_rx_packets < (unsigned int)budget)) {
@@ -2389,7 +2406,10 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget)
23892406
xdp.data_hard_start = xdp.data -
23902407
i40e_rx_offset(rx_ring);
23912408
xdp.data_end = xdp.data + size;
2392-
2409+
#if (PAGE_SIZE > 4096)
2410+
/* At larger PAGE_SIZE, frame_sz depend on len size */
2411+
xdp.frame_sz = i40e_rx_frame_truesize(rx_ring, size);
2412+
#endif
23932413
skb = i40e_run_xdp(rx_ring, &xdp);
23942414
}
23952415

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,12 +531,14 @@ int i40e_clean_rx_irq_zc(struct i40e_ring *rx_ring, int budget)
531531
{
532532
unsigned int total_rx_bytes = 0, total_rx_packets = 0;
533533
u16 cleaned_count = I40E_DESC_UNUSED(rx_ring);
534+
struct xdp_umem *umem = rx_ring->xsk_umem;
534535
unsigned int xdp_res, xdp_xmit = 0;
535536
bool failure = false;
536537
struct sk_buff *skb;
537538
struct xdp_buff xdp;
538539

539540
xdp.rxq = &rx_ring->xdp_rxq;
541+
xdp.frame_sz = xsk_umem_xdp_frame_sz(umem);
540542

541543
while (likely(total_rx_packets < (unsigned int)budget)) {
542544
struct i40e_rx_buffer *bi;

drivers/net/ethernet/intel/ice/ice_txrx.c

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,22 @@ static unsigned int ice_rx_offset(struct ice_ring *rx_ring)
423423
return 0;
424424
}
425425

426+
static unsigned int ice_rx_frame_truesize(struct ice_ring *rx_ring,
427+
unsigned int size)
428+
{
429+
unsigned int truesize;
430+
431+
#if (PAGE_SIZE < 8192)
432+
truesize = ice_rx_pg_size(rx_ring) / 2; /* Must be power-of-2 */
433+
#else
434+
truesize = ice_rx_offset(rx_ring) ?
435+
SKB_DATA_ALIGN(ice_rx_offset(rx_ring) + size) +
436+
SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) :
437+
SKB_DATA_ALIGN(size);
438+
#endif
439+
return truesize;
440+
}
441+
426442
/**
427443
* ice_run_xdp - Executes an XDP program on initialized xdp_buff
428444
* @rx_ring: Rx ring
@@ -991,6 +1007,10 @@ static int ice_clean_rx_irq(struct ice_ring *rx_ring, int budget)
9911007
bool failure;
9921008

9931009
xdp.rxq = &rx_ring->xdp_rxq;
1010+
/* Frame size depend on rx_ring setup when PAGE_SIZE=4K */
1011+
#if (PAGE_SIZE < 8192)
1012+
xdp.frame_sz = ice_rx_frame_truesize(rx_ring, 0);
1013+
#endif
9941014

9951015
/* start the loop to process Rx packets bounded by 'budget' */
9961016
while (likely(total_rx_pkts < (unsigned int)budget)) {
@@ -1038,6 +1058,10 @@ static int ice_clean_rx_irq(struct ice_ring *rx_ring, int budget)
10381058
xdp.data_hard_start = xdp.data - ice_rx_offset(rx_ring);
10391059
xdp.data_meta = xdp.data;
10401060
xdp.data_end = xdp.data + size;
1061+
#if (PAGE_SIZE > 4096)
1062+
/* At larger PAGE_SIZE, frame_sz depend on len size */
1063+
xdp.frame_sz = ice_rx_frame_truesize(rx_ring, size);
1064+
#endif
10411065

10421066
rcu_read_lock();
10431067
xdp_prog = READ_ONCE(rx_ring->xdp_prog);
@@ -1051,16 +1075,8 @@ static int ice_clean_rx_irq(struct ice_ring *rx_ring, int budget)
10511075
if (!xdp_res)
10521076
goto construct_skb;
10531077
if (xdp_res & (ICE_XDP_TX | ICE_XDP_REDIR)) {
1054-
unsigned int truesize;
1055-
1056-
#if (PAGE_SIZE < 8192)
1057-
truesize = ice_rx_pg_size(rx_ring) / 2;
1058-
#else
1059-
truesize = SKB_DATA_ALIGN(ice_rx_offset(rx_ring) +
1060-
size);
1061-
#endif
10621078
xdp_xmit |= xdp_res;
1063-
ice_rx_buf_adjust_pg_offset(rx_buf, truesize);
1079+
ice_rx_buf_adjust_pg_offset(rx_buf, xdp.frame_sz);
10641080
} else {
10651081
rx_buf->pagecnt_bias++;
10661082
}

drivers/net/ethernet/intel/ice/ice_xsk.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -840,11 +840,13 @@ int ice_clean_rx_irq_zc(struct ice_ring *rx_ring, int budget)
840840
{
841841
unsigned int total_rx_bytes = 0, total_rx_packets = 0;
842842
u16 cleaned_count = ICE_DESC_UNUSED(rx_ring);
843+
struct xdp_umem *umem = rx_ring->xsk_umem;
843844
unsigned int xdp_xmit = 0;
844845
bool failure = false;
845846
struct xdp_buff xdp;
846847

847848
xdp.rxq = &rx_ring->xdp_rxq;
849+
xdp.frame_sz = xsk_umem_xdp_frame_sz(umem);
848850

849851
while (likely(total_rx_packets < (unsigned int)budget)) {
850852
union ice_32b_rx_flex_desc *rx_desc;

drivers/net/ethernet/intel/ixgbe/ixgbe_main.c

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2244,19 +2244,30 @@ static struct sk_buff *ixgbe_run_xdp(struct ixgbe_adapter *adapter,
22442244
return ERR_PTR(-result);
22452245
}
22462246

2247+
static unsigned int ixgbe_rx_frame_truesize(struct ixgbe_ring *rx_ring,
2248+
unsigned int size)
2249+
{
2250+
unsigned int truesize;
2251+
2252+
#if (PAGE_SIZE < 8192)
2253+
truesize = ixgbe_rx_pg_size(rx_ring) / 2; /* Must be power-of-2 */
2254+
#else
2255+
truesize = ring_uses_build_skb(rx_ring) ?
2256+
SKB_DATA_ALIGN(IXGBE_SKB_PAD + size) +
2257+
SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) :
2258+
SKB_DATA_ALIGN(size);
2259+
#endif
2260+
return truesize;
2261+
}
2262+
22472263
static void ixgbe_rx_buffer_flip(struct ixgbe_ring *rx_ring,
22482264
struct ixgbe_rx_buffer *rx_buffer,
22492265
unsigned int size)
22502266
{
2267+
unsigned int truesize = ixgbe_rx_frame_truesize(rx_ring, size);
22512268
#if (PAGE_SIZE < 8192)
2252-
unsigned int truesize = ixgbe_rx_pg_size(rx_ring) / 2;
2253-
22542269
rx_buffer->page_offset ^= truesize;
22552270
#else
2256-
unsigned int truesize = ring_uses_build_skb(rx_ring) ?
2257-
SKB_DATA_ALIGN(IXGBE_SKB_PAD + size) :
2258-
SKB_DATA_ALIGN(size);
2259-
22602271
rx_buffer->page_offset += truesize;
22612272
#endif
22622273
}
@@ -2290,6 +2301,11 @@ static int ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
22902301

22912302
xdp.rxq = &rx_ring->xdp_rxq;
22922303

2304+
/* Frame size depend on rx_ring setup when PAGE_SIZE=4K */
2305+
#if (PAGE_SIZE < 8192)
2306+
xdp.frame_sz = ixgbe_rx_frame_truesize(rx_ring, 0);
2307+
#endif
2308+
22932309
while (likely(total_rx_packets < budget)) {
22942310
union ixgbe_adv_rx_desc *rx_desc;
22952311
struct ixgbe_rx_buffer *rx_buffer;
@@ -2323,7 +2339,10 @@ static int ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
23232339
xdp.data_hard_start = xdp.data -
23242340
ixgbe_rx_offset(rx_ring);
23252341
xdp.data_end = xdp.data + size;
2326-
2342+
#if (PAGE_SIZE > 4096)
2343+
/* At larger PAGE_SIZE, frame_sz depend on len size */
2344+
xdp.frame_sz = ixgbe_rx_frame_truesize(rx_ring, size);
2345+
#endif
23272346
skb = ixgbe_run_xdp(adapter, rx_ring, &xdp);
23282347
}
23292348

drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,12 +431,14 @@ int ixgbe_clean_rx_irq_zc(struct ixgbe_q_vector *q_vector,
431431
unsigned int total_rx_bytes = 0, total_rx_packets = 0;
432432
struct ixgbe_adapter *adapter = q_vector->adapter;
433433
u16 cleaned_count = ixgbe_desc_unused(rx_ring);
434+
struct xdp_umem *umem = rx_ring->xsk_umem;
434435
unsigned int xdp_res, xdp_xmit = 0;
435436
bool failure = false;
436437
struct sk_buff *skb;
437438
struct xdp_buff xdp;
438439

439440
xdp.rxq = &rx_ring->xdp_rxq;
441+
xdp.frame_sz = xsk_umem_xdp_frame_sz(umem);
440442

441443
while (likely(total_rx_packets < budget)) {
442444
union ixgbe_adv_rx_desc *rx_desc;

drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,19 +1095,31 @@ static struct sk_buff *ixgbevf_run_xdp(struct ixgbevf_adapter *adapter,
10951095
return ERR_PTR(-result);
10961096
}
10971097

1098+
static unsigned int ixgbevf_rx_frame_truesize(struct ixgbevf_ring *rx_ring,
1099+
unsigned int size)
1100+
{
1101+
unsigned int truesize;
1102+
1103+
#if (PAGE_SIZE < 8192)
1104+
truesize = ixgbevf_rx_pg_size(rx_ring) / 2; /* Must be power-of-2 */
1105+
#else
1106+
truesize = ring_uses_build_skb(rx_ring) ?
1107+
SKB_DATA_ALIGN(IXGBEVF_SKB_PAD + size) +
1108+
SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) :
1109+
SKB_DATA_ALIGN(size);
1110+
#endif
1111+
return truesize;
1112+
}
1113+
10981114
static void ixgbevf_rx_buffer_flip(struct ixgbevf_ring *rx_ring,
10991115
struct ixgbevf_rx_buffer *rx_buffer,
11001116
unsigned int size)
11011117
{
1102-
#if (PAGE_SIZE < 8192)
1103-
unsigned int truesize = ixgbevf_rx_pg_size(rx_ring) / 2;
1118+
unsigned int truesize = ixgbevf_rx_frame_truesize(rx_ring, size);
11041119

1120+
#if (PAGE_SIZE < 8192)
11051121
rx_buffer->page_offset ^= truesize;
11061122
#else
1107-
unsigned int truesize = ring_uses_build_skb(rx_ring) ?
1108-
SKB_DATA_ALIGN(IXGBEVF_SKB_PAD + size) :
1109-
SKB_DATA_ALIGN(size);
1110-
11111123
rx_buffer->page_offset += truesize;
11121124
#endif
11131125
}
@@ -1125,6 +1137,11 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector,
11251137

11261138
xdp.rxq = &rx_ring->xdp_rxq;
11271139

1140+
/* Frame size depend on rx_ring setup when PAGE_SIZE=4K */
1141+
#if (PAGE_SIZE < 8192)
1142+
xdp.frame_sz = ixgbevf_rx_frame_truesize(rx_ring, 0);
1143+
#endif
1144+
11281145
while (likely(total_rx_packets < budget)) {
11291146
struct ixgbevf_rx_buffer *rx_buffer;
11301147
union ixgbe_adv_rx_desc *rx_desc;
@@ -1157,7 +1174,10 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector,
11571174
xdp.data_hard_start = xdp.data -
11581175
ixgbevf_rx_offset(rx_ring);
11591176
xdp.data_end = xdp.data + size;
1160-
1177+
#if (PAGE_SIZE > 4096)
1178+
/* At larger PAGE_SIZE, frame_sz depend on len size */
1179+
xdp.frame_sz = ixgbevf_rx_frame_truesize(rx_ring, size);
1180+
#endif
11611181
skb = ixgbevf_run_xdp(adapter, rx_ring, &xdp);
11621182
}
11631183

0 commit comments

Comments
 (0)