Thread (5 messages) 5 messages, 4 authors, 1d ago

RE: [Intel-wired-lan] [PATCH net] i40e: xsk: fix multi-buffer XDP_PASS skb construction

From: Loktionov, Aleksandr <hidden>
Date: 2026-07-15 09:38:25
Also in: intel-wired-lan

quoted hunk ↗ jump to hunk
-----Original Message-----
From: Intel-wired-lan <redacted> On Behalf
Of Chenguang Zhao
Sent: Tuesday, July 14, 2026 4:51 AM
To: Nguyen, Anthony L <anthony.l.nguyen@intel.com>; Kitszel,
Przemyslaw [off-list ref]; andrew+netdev@lunn.ch;
davem@davemloft.net; edumazet@google.com; kuba@kernel.org;
pabeni@redhat.com
Cc: intel-wired-lan@lists.osuosl.org; netdev@vger.kernel.org;
chenguang.zhao@linux.dev; Chenguang Zhao [off-list ref]
Subject: [Intel-wired-lan] [PATCH net] i40e: xsk: fix multi-buffer
XDP_PASS skb construction

From: Chenguang Zhao <redacted>

When AF_XDP ZC receives a multi-buffer frame and the XDP program
returns XDP_PASS, i40e_construct_skb_zc() copies frags into a new skb.
The copy used skb_frag_page() as the memcpy source (page metadata
instead of packet data) and passed a virtual address to
__skb_fill_page_desc_noacc(), which expects a struct page *.

Use skb_frag_address() for the copy, attach frags with
skb_add_rx_frag() so len/data_len/truesize are updated, and on
dev_alloc_page() failure free the skb via the shared out path so
xsk_buff_free() still runs and previously attached pages are released
by kfree_skb.

Fixes: 1c9ba9c14658 ("i40e: xsk: add RX multi-buffer support")
Signed-off-by: Chenguang Zhao <redacted>
---
 - Fix memcpy source: use skb_frag_address() instead of
skb_frag_page(),
   which was copying page metadata rather than packet data.

 - Fix frag attachment: pass the allocated struct page * to the skb
frag
   helper instead of the page virtual address.

 - Use skb_add_rx_frag() so skb->len, data_len and truesize are
updated
   when attaching copied frags.

 - On mid-loop dev_alloc_page() failure, go through the shared out
path
   so previously attached pages are released via kfree_skb and
   xsk_buff_free() is still called.

 drivers/net/ethernet/intel/i40e/i40e_xsk.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_xsk.c
b/drivers/net/ethernet/intel/i40e/i40e_xsk.c
index 9f47388eaba5..a4247710c85b 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_xsk.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_xsk.c
@@ -318,22 +318,19 @@ static struct sk_buff
*i40e_construct_skb_zc(struct i40e_ring *rx_ring,
 		goto out;

 	for (int i = 0; i < nr_frags; i++) {
-		struct skb_shared_info *skinfo = skb_shinfo(skb);
 		skb_frag_t *frag = &sinfo->frags[i];
+		unsigned int frag_size = skb_frag_size(frag);
 		struct page *page;
-		void *addr;

 		page = dev_alloc_page();
 		if (!page) {
 			dev_kfree_skb(skb);
-			return NULL;
+			skb = NULL;
+			goto out;
 		}
-		addr = page_to_virt(page);

-		memcpy(addr, skb_frag_page(frag), skb_frag_size(frag));
-
-		__skb_fill_page_desc_noacc(skinfo, skinfo->nr_frags++,
-					   addr, 0, skb_frag_size(frag));
+		memcpy(page_to_virt(page), skb_frag_address(frag),
frag_size);
+		skb_add_rx_frag(skb, i, page, 0, frag_size, PAGE_SIZE);
 	}

 out:
--
2.25.1
Reviewed-by: Aleksandr Loktionov <redacted>
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help