netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next 0/2] net: xdp: handle frags with unreadable memory
@ 2025-09-05 22:15 Jakub Kicinski
  2025-09-05 22:15 ` [PATCH net-next 1/2] net: xdp: pass full flags to xdp_update_skb_shared_info() Jakub Kicinski
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Jakub Kicinski @ 2025-09-05 22:15 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, andrew+netdev, horms, daniel, hawk,
	john.fastabend, sdf, michael.chan, anthony.l.nguyen,
	marcin.s.wojtas, tariqt, mbloch, jasowang, bpf,
	aleksander.lobakin, pavan.chebbi, przemyslaw.kitszel,
	Jakub Kicinski

Make XDP helpers compatible with unreadable memory. This is very
similar to how we handle pfmemalloc frags today. Record the info
in xdp_buf flags as frags get added and then update the skb once
allocated.

This series adds the unreadable memory metadata tracking to drivers
using xdp_build_skb_from*() with no changes on the driver side - hence
the only driver changes here are refactoring. Obviously, unreadable memory
is incompatible with XDP today, but thanks to xdp_build_skb_from_buf()
increasing number of drivers have a unified datapath, whether XDP is
enabled or not.

RFC: https://lore.kernel.org/20250812161528.835855-1-kuba@kernel.org

Jakub Kicinski (2):
  net: xdp: pass full flags to xdp_update_skb_shared_info()
  net: xdp: handle frags with unreadable memory

 include/net/xdp.h                             | 38 ++++++++++++-------
 drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c |  7 ++--
 drivers/net/ethernet/intel/i40e/i40e_txrx.c   | 15 ++++----
 drivers/net/ethernet/intel/ice/ice_txrx.c     | 15 ++++----
 drivers/net/ethernet/marvell/mvneta.c         |  7 ++--
 .../net/ethernet/mellanox/mlx5/core/en_rx.c   | 23 ++++++-----
 drivers/net/virtio_net.c                      |  7 ++--
 net/core/xdp.c                                | 21 +++++-----
 8 files changed, 69 insertions(+), 64 deletions(-)

-- 
2.51.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH net-next 1/2] net: xdp: pass full flags to xdp_update_skb_shared_info()
  2025-09-05 22:15 [PATCH net-next 0/2] net: xdp: handle frags with unreadable memory Jakub Kicinski
@ 2025-09-05 22:15 ` Jakub Kicinski
  2025-09-09 13:30   ` Jesper Dangaard Brouer
  2025-09-05 22:15 ` [PATCH net-next 2/2] net: xdp: handle frags with unreadable memory Jakub Kicinski
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 8+ messages in thread
From: Jakub Kicinski @ 2025-09-05 22:15 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, andrew+netdev, horms, daniel, hawk,
	john.fastabend, sdf, michael.chan, anthony.l.nguyen,
	marcin.s.wojtas, tariqt, mbloch, jasowang, bpf,
	aleksander.lobakin, pavan.chebbi, przemyslaw.kitszel,
	Jakub Kicinski

xdp_update_skb_shared_info() needs to update skb state which
was maintained in xdp_buff / frame. Pass full flags into it,
instead of breaking it out bit by bit. We will need to add
a bit for unreadable frags (even tho XDP doesn't support
those the driver paths may be common), at which point almost
all call sites would become:

    xdp_update_skb_shared_info(skb, num_frags,
                               sinfo->xdp_frags_size,
                               MY_PAGE_SIZE * num_frags,
                               xdp_buff_is_frag_pfmemalloc(xdp),
                               xdp_buff_is_frag_unreadable(xdp));

Keep a helper for accessing the flags, in case we need to
transform them somehow in the future (e.g. to cover up xdp_buff
vs xdp_frame differences).

While we are touching call callers - rename the helper to
xdp_update_skb_frags_info(), previous name may have implied that
it's shinfo that's updated. We are updating flags in struct sk_buff
based on frags that got attched.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
v1:
 - rename skb_flags arg to xdp_flags
 - rename xdp_update_skb_shared_info() -> xdp_update_skb_frags_info()
RFC: https://lore.kernel.org/20250812161528.835855-1-kuba@kernel.org
---
 include/net/xdp.h                             | 25 +++++++++----------
 drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c |  7 +++---
 drivers/net/ethernet/intel/i40e/i40e_txrx.c   | 15 ++++++-----
 drivers/net/ethernet/intel/ice/ice_txrx.c     | 15 ++++++-----
 drivers/net/ethernet/marvell/mvneta.c         |  7 +++---
 .../net/ethernet/mellanox/mlx5/core/en_rx.c   | 23 ++++++++---------
 drivers/net/virtio_net.c                      |  7 +++---
 net/core/xdp.c                                | 21 ++++++++--------
 8 files changed, 56 insertions(+), 64 deletions(-)

diff --git a/include/net/xdp.h b/include/net/xdp.h
index b40f1f96cb11..57189fc21168 100644
--- a/include/net/xdp.h
+++ b/include/net/xdp.h
@@ -104,17 +104,16 @@ static __always_inline void xdp_buff_clear_frags_flag(struct xdp_buff *xdp)
 	xdp->flags &= ~XDP_FLAGS_HAS_FRAGS;
 }
 
-static __always_inline bool
-xdp_buff_is_frag_pfmemalloc(const struct xdp_buff *xdp)
-{
-	return !!(xdp->flags & XDP_FLAGS_FRAGS_PF_MEMALLOC);
-}
-
 static __always_inline void xdp_buff_set_frag_pfmemalloc(struct xdp_buff *xdp)
 {
 	xdp->flags |= XDP_FLAGS_FRAGS_PF_MEMALLOC;
 }
 
+static __always_inline u32 xdp_buff_get_skb_flags(const struct xdp_buff *xdp)
+{
+	return xdp->flags;
+}
+
 static __always_inline void
 xdp_init_buff(struct xdp_buff *xdp, u32 frame_sz, struct xdp_rxq_info *rxq)
 {
@@ -272,10 +271,10 @@ static __always_inline bool xdp_frame_has_frags(const struct xdp_frame *frame)
 	return !!(frame->flags & XDP_FLAGS_HAS_FRAGS);
 }
 
-static __always_inline bool
-xdp_frame_is_frag_pfmemalloc(const struct xdp_frame *frame)
+static __always_inline u32
+xdp_frame_get_skb_flags(const struct xdp_frame *frame)
 {
-	return !!(frame->flags & XDP_FLAGS_FRAGS_PF_MEMALLOC);
+	return frame->flags;
 }
 
 #define XDP_BULK_QUEUE_SIZE	16
@@ -312,9 +311,9 @@ static inline void xdp_scrub_frame(struct xdp_frame *frame)
 }
 
 static inline void
-xdp_update_skb_shared_info(struct sk_buff *skb, u8 nr_frags,
-			   unsigned int size, unsigned int truesize,
-			   bool pfmemalloc)
+xdp_update_skb_frags_info(struct sk_buff *skb, u8 nr_frags,
+			  unsigned int size, unsigned int truesize,
+			  u32 xdp_flags)
 {
 	struct skb_shared_info *sinfo = skb_shinfo(skb);
 
@@ -328,7 +327,7 @@ xdp_update_skb_shared_info(struct sk_buff *skb, u8 nr_frags,
 	skb->len += size;
 	skb->data_len += size;
 	skb->truesize += truesize;
-	skb->pfmemalloc |= pfmemalloc;
+	skb->pfmemalloc |= !!(xdp_flags & XDP_FLAGS_FRAGS_PF_MEMALLOC);
 }
 
 /* Avoids inlining WARN macro in fast-path */
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
index 58d579dca3f1..3e77a96e5a3e 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
@@ -468,9 +468,8 @@ bnxt_xdp_build_skb(struct bnxt *bp, struct sk_buff *skb, u8 num_frags,
 	if (!skb)
 		return NULL;
 
-	xdp_update_skb_shared_info(skb, num_frags,
-				   sinfo->xdp_frags_size,
-				   BNXT_RX_PAGE_SIZE * num_frags,
-				   xdp_buff_is_frag_pfmemalloc(xdp));
+	xdp_update_skb_frags_info(skb, num_frags, sinfo->xdp_frags_size,
+				  BNXT_RX_PAGE_SIZE * num_frags,
+				  xdp_buff_get_skb_flags(xdp));
 	return skb;
 }
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
index 048c33039130..98601c62c592 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
@@ -2151,10 +2151,10 @@ static struct sk_buff *i40e_construct_skb(struct i40e_ring *rx_ring,
 		memcpy(&skinfo->frags[skinfo->nr_frags], &sinfo->frags[0],
 		       sizeof(skb_frag_t) * nr_frags);
 
-		xdp_update_skb_shared_info(skb, skinfo->nr_frags + nr_frags,
-					   sinfo->xdp_frags_size,
-					   nr_frags * xdp->frame_sz,
-					   xdp_buff_is_frag_pfmemalloc(xdp));
+		xdp_update_skb_frags_info(skb, skinfo->nr_frags + nr_frags,
+					  sinfo->xdp_frags_size,
+					  nr_frags * xdp->frame_sz,
+					  xdp_buff_get_skb_flags(xdp));
 
 		/* First buffer has already been processed, so bump ntc */
 		if (++rx_ring->next_to_clean == rx_ring->count)
@@ -2206,10 +2206,9 @@ static struct sk_buff *i40e_build_skb(struct i40e_ring *rx_ring,
 		skb_metadata_set(skb, metasize);
 
 	if (unlikely(xdp_buff_has_frags(xdp))) {
-		xdp_update_skb_shared_info(skb, nr_frags,
-					   sinfo->xdp_frags_size,
-					   nr_frags * xdp->frame_sz,
-					   xdp_buff_is_frag_pfmemalloc(xdp));
+		xdp_update_skb_frags_info(skb, nr_frags, sinfo->xdp_frags_size,
+					  nr_frags * xdp->frame_sz,
+					  xdp_buff_get_skb_flags(xdp));
 
 		i40e_process_rx_buffs(rx_ring, I40E_XDP_PASS, xdp);
 	} else {
diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c
index d2871757ec94..107632a71f3c 100644
--- a/drivers/net/ethernet/intel/ice/ice_txrx.c
+++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
@@ -1035,10 +1035,9 @@ ice_build_skb(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp)
 		skb_metadata_set(skb, metasize);
 
 	if (unlikely(xdp_buff_has_frags(xdp)))
-		xdp_update_skb_shared_info(skb, nr_frags,
-					   sinfo->xdp_frags_size,
-					   nr_frags * xdp->frame_sz,
-					   xdp_buff_is_frag_pfmemalloc(xdp));
+		xdp_update_skb_frags_info(skb, nr_frags, sinfo->xdp_frags_size,
+					  nr_frags * xdp->frame_sz,
+					  xdp_buff_get_skb_flags(xdp));
 
 	return skb;
 }
@@ -1115,10 +1114,10 @@ ice_construct_skb(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp)
 		memcpy(&skinfo->frags[skinfo->nr_frags], &sinfo->frags[0],
 		       sizeof(skb_frag_t) * nr_frags);
 
-		xdp_update_skb_shared_info(skb, skinfo->nr_frags + nr_frags,
-					   sinfo->xdp_frags_size,
-					   nr_frags * xdp->frame_sz,
-					   xdp_buff_is_frag_pfmemalloc(xdp));
+		xdp_update_skb_frags_info(skb, skinfo->nr_frags + nr_frags,
+					  sinfo->xdp_frags_size,
+					  nr_frags * xdp->frame_sz,
+					  xdp_buff_get_skb_flags(xdp));
 	}
 
 	return skb;
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 476e73e502fe..7351e98d73f4 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -2416,10 +2416,9 @@ mvneta_swbm_build_skb(struct mvneta_port *pp, struct page_pool *pool,
 	skb->ip_summed = mvneta_rx_csum(pp, desc_status);
 
 	if (unlikely(xdp_buff_has_frags(xdp)))
-		xdp_update_skb_shared_info(skb, num_frags,
-					   sinfo->xdp_frags_size,
-					   num_frags * xdp->frame_sz,
-					   xdp_buff_is_frag_pfmemalloc(xdp));
+		xdp_update_skb_frags_info(skb, num_frags, sinfo->xdp_frags_size,
+					  num_frags * xdp->frame_sz,
+					  xdp_buff_get_skb_flags(xdp));
 
 	return skb;
 }
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
index b8c609d91d11..2925ece136c4 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -1796,10 +1796,9 @@ mlx5e_skb_from_cqe_nonlinear(struct mlx5e_rq *rq, struct mlx5e_wqe_frag_info *wi
 
 	if (xdp_buff_has_frags(&mxbuf->xdp)) {
 		/* sinfo->nr_frags is reset by build_skb, calculate again. */
-		xdp_update_skb_shared_info(skb, wi - head_wi - 1,
-					   sinfo->xdp_frags_size, truesize,
-					   xdp_buff_is_frag_pfmemalloc(
-						&mxbuf->xdp));
+		xdp_update_skb_frags_info(skb, wi - head_wi - 1,
+					  sinfo->xdp_frags_size, truesize,
+					  xdp_buff_get_skb_flags(&mxbuf->xdp));
 
 		for (struct mlx5e_wqe_frag_info *pwi = head_wi + 1; pwi < wi; pwi++)
 			pwi->frag_page->frags++;
@@ -2105,10 +2104,10 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w
 			struct mlx5e_frag_page *pagep;
 
 			/* sinfo->nr_frags is reset by build_skb, calculate again. */
-			xdp_update_skb_shared_info(skb, frag_page - head_page,
-						   sinfo->xdp_frags_size, truesize,
-						   xdp_buff_is_frag_pfmemalloc(
-							&mxbuf->xdp));
+			xdp_update_skb_frags_info(skb, frag_page - head_page,
+						  sinfo->xdp_frags_size,
+						  truesize,
+						  xdp_buff_get_skb_flags(&mxbuf->xdp));
 
 			pagep = head_page;
 			do
@@ -2122,10 +2121,10 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w
 		if (xdp_buff_has_frags(&mxbuf->xdp)) {
 			struct mlx5e_frag_page *pagep;
 
-			xdp_update_skb_shared_info(skb, sinfo->nr_frags,
-						   sinfo->xdp_frags_size, truesize,
-						   xdp_buff_is_frag_pfmemalloc(
-							&mxbuf->xdp));
+			xdp_update_skb_frags_info(skb, sinfo->nr_frags,
+						  sinfo->xdp_frags_size,
+						  truesize,
+						  xdp_buff_get_skb_flags(&mxbuf->xdp));
 
 			pagep = frag_page - sinfo->nr_frags;
 			do
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 975bdc5dab84..06708c9a979e 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -2185,10 +2185,9 @@ static struct sk_buff *build_skb_from_xdp_buff(struct net_device *dev,
 		skb_metadata_set(skb, metasize);
 
 	if (unlikely(xdp_buff_has_frags(xdp)))
-		xdp_update_skb_shared_info(skb, nr_frags,
-					   sinfo->xdp_frags_size,
-					   xdp_frags_truesz,
-					   xdp_buff_is_frag_pfmemalloc(xdp));
+		xdp_update_skb_frags_info(skb, nr_frags, sinfo->xdp_frags_size,
+					  xdp_frags_truesz,
+					  xdp_buff_get_skb_flags(xdp));
 
 	return skb;
 }
diff --git a/net/core/xdp.c b/net/core/xdp.c
index 491334b9b8be..9100e160113a 100644
--- a/net/core/xdp.c
+++ b/net/core/xdp.c
@@ -663,9 +663,8 @@ struct sk_buff *xdp_build_skb_from_buff(const struct xdp_buff *xdp)
 		u32 tsize;
 
 		tsize = sinfo->xdp_frags_truesize ? : nr_frags * xdp->frame_sz;
-		xdp_update_skb_shared_info(skb, nr_frags,
-					   sinfo->xdp_frags_size, tsize,
-					   xdp_buff_is_frag_pfmemalloc(xdp));
+		xdp_update_skb_frags_info(skb, nr_frags, sinfo->xdp_frags_size,
+					  tsize, xdp_buff_get_skb_flags(xdp));
 	}
 
 	skb->protocol = eth_type_trans(skb, rxq->dev);
@@ -692,7 +691,7 @@ static noinline bool xdp_copy_frags_from_zc(struct sk_buff *skb,
 	struct skb_shared_info *sinfo = skb_shinfo(skb);
 	const struct skb_shared_info *xinfo;
 	u32 nr_frags, tsize = 0;
-	bool pfmemalloc = false;
+	u32 flags = 0;
 
 	xinfo = xdp_get_shared_info_from_buff(xdp);
 	nr_frags = xinfo->nr_frags;
@@ -714,11 +713,12 @@ static noinline bool xdp_copy_frags_from_zc(struct sk_buff *skb,
 		__skb_fill_page_desc_noacc(sinfo, i, page, offset, len);
 
 		tsize += truesize;
-		pfmemalloc |= page_is_pfmemalloc(page);
+		if (page_is_pfmemalloc(page))
+			flags |= XDP_FLAGS_FRAGS_PF_MEMALLOC;
 	}
 
-	xdp_update_skb_shared_info(skb, nr_frags, xinfo->xdp_frags_size,
-				   tsize, pfmemalloc);
+	xdp_update_skb_frags_info(skb, nr_frags, xinfo->xdp_frags_size, tsize,
+				  flags);
 
 	return true;
 }
@@ -823,10 +823,9 @@ struct sk_buff *__xdp_build_skb_from_frame(struct xdp_frame *xdpf,
 		skb_metadata_set(skb, xdpf->metasize);
 
 	if (unlikely(xdp_frame_has_frags(xdpf)))
-		xdp_update_skb_shared_info(skb, nr_frags,
-					   sinfo->xdp_frags_size,
-					   nr_frags * xdpf->frame_sz,
-					   xdp_frame_is_frag_pfmemalloc(xdpf));
+		xdp_update_skb_frags_info(skb, nr_frags, sinfo->xdp_frags_size,
+					  nr_frags * xdpf->frame_sz,
+					  xdp_frame_get_skb_flags(xdpf));
 
 	/* Essential SKB info: protocol and skb->dev */
 	skb->protocol = eth_type_trans(skb, dev);
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH net-next 2/2] net: xdp: handle frags with unreadable memory
  2025-09-05 22:15 [PATCH net-next 0/2] net: xdp: handle frags with unreadable memory Jakub Kicinski
  2025-09-05 22:15 ` [PATCH net-next 1/2] net: xdp: pass full flags to xdp_update_skb_shared_info() Jakub Kicinski
@ 2025-09-05 22:15 ` Jakub Kicinski
  2025-09-05 22:55 ` [PATCH net-next 0/2] " Stanislav Fomichev
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Jakub Kicinski @ 2025-09-05 22:15 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, andrew+netdev, horms, daniel, hawk,
	john.fastabend, sdf, michael.chan, anthony.l.nguyen,
	marcin.s.wojtas, tariqt, mbloch, jasowang, bpf,
	aleksander.lobakin, pavan.chebbi, przemyslaw.kitszel,
	Jakub Kicinski

We don't expect frags with unreadable memory to be presented
to XDP programs today, but the XDP helpers are designed to be
usable whether XDP is enabled or not. Support handling frags
with unreadable memory.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 include/net/xdp.h | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/include/net/xdp.h b/include/net/xdp.h
index 57189fc21168..98f984d8f2c6 100644
--- a/include/net/xdp.h
+++ b/include/net/xdp.h
@@ -76,6 +76,11 @@ enum xdp_buff_flags {
 	XDP_FLAGS_FRAGS_PF_MEMALLOC	= BIT(1), /* xdp paged memory is under
 						   * pressure
 						   */
+	/* frags have unreadable mem, this can't be true for real XDP packets,
+	 * but drivers may use XDP helpers to construct Rx pkt state even when
+	 * XDP program is not attached.
+	 */
+	XDP_FLAGS_FRAGS_UNREADABLE	= BIT(2),
 };
 
 struct xdp_buff {
@@ -109,6 +114,11 @@ static __always_inline void xdp_buff_set_frag_pfmemalloc(struct xdp_buff *xdp)
 	xdp->flags |= XDP_FLAGS_FRAGS_PF_MEMALLOC;
 }
 
+static __always_inline void xdp_buff_set_frag_unreadable(struct xdp_buff *xdp)
+{
+	xdp->flags |= XDP_FLAGS_FRAGS_UNREADABLE;
+}
+
 static __always_inline u32 xdp_buff_get_skb_flags(const struct xdp_buff *xdp)
 {
 	return xdp->flags;
@@ -248,6 +258,8 @@ static inline bool xdp_buff_add_frag(struct xdp_buff *xdp, netmem_ref netmem,
 
 	if (unlikely(netmem_is_pfmemalloc(netmem)))
 		xdp_buff_set_frag_pfmemalloc(xdp);
+	if (unlikely(netmem_is_net_iov(netmem)))
+		xdp_buff_set_frag_unreadable(xdp);
 
 	return true;
 }
@@ -328,6 +340,7 @@ xdp_update_skb_frags_info(struct sk_buff *skb, u8 nr_frags,
 	skb->data_len += size;
 	skb->truesize += truesize;
 	skb->pfmemalloc |= !!(xdp_flags & XDP_FLAGS_FRAGS_PF_MEMALLOC);
+	skb->unreadable |= !!(xdp_flags & XDP_FLAGS_FRAGS_UNREADABLE);
 }
 
 /* Avoids inlining WARN macro in fast-path */
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next 0/2] net: xdp: handle frags with unreadable memory
  2025-09-05 22:15 [PATCH net-next 0/2] net: xdp: handle frags with unreadable memory Jakub Kicinski
  2025-09-05 22:15 ` [PATCH net-next 1/2] net: xdp: pass full flags to xdp_update_skb_shared_info() Jakub Kicinski
  2025-09-05 22:15 ` [PATCH net-next 2/2] net: xdp: handle frags with unreadable memory Jakub Kicinski
@ 2025-09-05 22:55 ` Stanislav Fomichev
  2025-09-08 12:02 ` Alexander Lobakin
  2025-09-11 10:10 ` patchwork-bot+netdevbpf
  4 siblings, 0 replies; 8+ messages in thread
From: Stanislav Fomichev @ 2025-09-05 22:55 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, daniel,
	hawk, john.fastabend, sdf, michael.chan, anthony.l.nguyen,
	marcin.s.wojtas, tariqt, mbloch, jasowang, bpf,
	aleksander.lobakin, pavan.chebbi, przemyslaw.kitszel

On 09/05, Jakub Kicinski wrote:
> Make XDP helpers compatible with unreadable memory. This is very
> similar to how we handle pfmemalloc frags today. Record the info
> in xdp_buf flags as frags get added and then update the skb once
> allocated.
> 
> This series adds the unreadable memory metadata tracking to drivers
> using xdp_build_skb_from*() with no changes on the driver side - hence
> the only driver changes here are refactoring. Obviously, unreadable memory
> is incompatible with XDP today, but thanks to xdp_build_skb_from_buf()
> increasing number of drivers have a unified datapath, whether XDP is
> enabled or not.
> 
> RFC: https://lore.kernel.org/20250812161528.835855-1-kuba@kernel.org

Acked-by: Stanislav Fomichev <sdf@fomichev.me>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next 0/2] net: xdp: handle frags with unreadable memory
  2025-09-05 22:15 [PATCH net-next 0/2] net: xdp: handle frags with unreadable memory Jakub Kicinski
                   ` (2 preceding siblings ...)
  2025-09-05 22:55 ` [PATCH net-next 0/2] " Stanislav Fomichev
@ 2025-09-08 12:02 ` Alexander Lobakin
  2025-09-11 10:10 ` patchwork-bot+netdevbpf
  4 siblings, 0 replies; 8+ messages in thread
From: Alexander Lobakin @ 2025-09-08 12:02 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, daniel,
	hawk, john.fastabend, sdf, michael.chan, anthony.l.nguyen,
	marcin.s.wojtas, tariqt, mbloch, jasowang, bpf, pavan.chebbi,
	przemyslaw.kitszel

From: Jakub Kicinski <kuba@kernel.org>
Date: Fri,  5 Sep 2025 15:15:37 -0700

> Make XDP helpers compatible with unreadable memory. This is very
> similar to how we handle pfmemalloc frags today. Record the info
> in xdp_buf flags as frags get added and then update the skb once
> allocated.
> 
> This series adds the unreadable memory metadata tracking to drivers
> using xdp_build_skb_from*() with no changes on the driver side - hence
> the only driver changes here are refactoring. Obviously, unreadable memory
> is incompatible with XDP today, but thanks to xdp_build_skb_from_buf()
> increasing number of drivers have a unified datapath, whether XDP is
> enabled or not.
> 
> RFC: https://lore.kernel.org/20250812161528.835855-1-kuba@kernel.org

Reviewed-by: Alexander Lobakin <aleksander.lobakin@intel.com>

I have plans to add possibility to run XDP progs on devmem/io_uring
queues when it's known that the program doesn't heed to access the
payload, only the headers. Currently no free time slots for this, but
eventually we'll get there. This is a good prereq for this.

Thanks,
Olek

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next 1/2] net: xdp: pass full flags to xdp_update_skb_shared_info()
  2025-09-05 22:15 ` [PATCH net-next 1/2] net: xdp: pass full flags to xdp_update_skb_shared_info() Jakub Kicinski
@ 2025-09-09 13:30   ` Jesper Dangaard Brouer
  2025-09-09 23:24     ` Jakub Kicinski
  0 siblings, 1 reply; 8+ messages in thread
From: Jesper Dangaard Brouer @ 2025-09-09 13:30 UTC (permalink / raw)
  To: Jakub Kicinski, davem
  Cc: netdev, edumazet, pabeni, andrew+netdev, horms, daniel,
	john.fastabend, sdf, michael.chan, anthony.l.nguyen,
	marcin.s.wojtas, tariqt, mbloch, jasowang, bpf,
	aleksander.lobakin, pavan.chebbi, przemyslaw.kitszel



On 06/09/2025 00.15, Jakub Kicinski wrote:
> xdp_update_skb_shared_info() needs to update skb state which
> was maintained in xdp_buff / frame. Pass full flags into it,
> instead of breaking it out bit by bit. We will need to add
> a bit for unreadable frags (even tho XDP doesn't support
> those the driver paths may be common), at which point almost
> all call sites would become:
> 
>      xdp_update_skb_shared_info(skb, num_frags,
>                                 sinfo->xdp_frags_size,
>                                 MY_PAGE_SIZE * num_frags,
>                                 xdp_buff_is_frag_pfmemalloc(xdp),
>                                 xdp_buff_is_frag_unreadable(xdp));
> 
> Keep a helper for accessing the flags, in case we need to
> transform them somehow in the future (e.g. to cover up xdp_buff
> vs xdp_frame differences).
> 
> While we are touching call callers - rename the helper to
> xdp_update_skb_frags_info(), previous name may have implied that
> it's shinfo that's updated. We are updating flags in struct sk_buff
> based on frags that got attched.
typo                      ^^^^^^^

> 

I'm fine with the name xdp_update_skb_frags_info().
But I want to point out that the function *does* also update shinfo.
The xdp_buff/xdp-frame have a compatible layout for shinfo, except for a
union with sinfo->destructor_arg, which we need to clear.  This is a
transition point from XDP to SKB, which is why I think the function name
change is appropiate.

> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> ---
> v1:
>   - rename skb_flags arg to xdp_flags

Thanks for that. You kept the function name xdp_buff_get_skb_flags(),
indicating this is "skb_flags".  I don't think it matters much, so to
avoid bikesheeting I'm just going to ACK this.

Acked-by: Jesper Dangaard Brouer <hawk@kernel.org>

--Jesper

>   - rename xdp_update_skb_shared_info() -> xdp_update_skb_frags_info()
> RFC: https://lore.kernel.org/20250812161528.835855-1-kuba@kernel.org
> ---
>   include/net/xdp.h                             | 25 +++++++++----------
>   drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c |  7 +++---
>   drivers/net/ethernet/intel/i40e/i40e_txrx.c   | 15 ++++++-----
>   drivers/net/ethernet/intel/ice/ice_txrx.c     | 15 ++++++-----
>   drivers/net/ethernet/marvell/mvneta.c         |  7 +++---
>   .../net/ethernet/mellanox/mlx5/core/en_rx.c   | 23 ++++++++---------
>   drivers/net/virtio_net.c                      |  7 +++---
>   net/core/xdp.c                                | 21 ++++++++--------
>   8 files changed, 56 insertions(+), 64 deletions(-)
> 
> diff --git a/include/net/xdp.h b/include/net/xdp.h
> index b40f1f96cb11..57189fc21168 100644
> --- a/include/net/xdp.h
> +++ b/include/net/xdp.h
> @@ -104,17 +104,16 @@ static __always_inline void xdp_buff_clear_frags_flag(struct xdp_buff *xdp)
>   	xdp->flags &= ~XDP_FLAGS_HAS_FRAGS;
>   }
>   
> -static __always_inline bool
> -xdp_buff_is_frag_pfmemalloc(const struct xdp_buff *xdp)
> -{
> -	return !!(xdp->flags & XDP_FLAGS_FRAGS_PF_MEMALLOC);
> -}
> -
>   static __always_inline void xdp_buff_set_frag_pfmemalloc(struct xdp_buff *xdp)
>   {
>   	xdp->flags |= XDP_FLAGS_FRAGS_PF_MEMALLOC;
>   }
>   
> +static __always_inline u32 xdp_buff_get_skb_flags(const struct xdp_buff *xdp)
> +{
> +	return xdp->flags;
> +}
> +
>   static __always_inline void
>   xdp_init_buff(struct xdp_buff *xdp, u32 frame_sz, struct xdp_rxq_info *rxq)
>   {
> @@ -272,10 +271,10 @@ static __always_inline bool xdp_frame_has_frags(const struct xdp_frame *frame)
>   	return !!(frame->flags & XDP_FLAGS_HAS_FRAGS);
>   }
>   
> -static __always_inline bool
> -xdp_frame_is_frag_pfmemalloc(const struct xdp_frame *frame)
> +static __always_inline u32
> +xdp_frame_get_skb_flags(const struct xdp_frame *frame)
>   {
> -	return !!(frame->flags & XDP_FLAGS_FRAGS_PF_MEMALLOC);
> +	return frame->flags;
>   }
>   
>   #define XDP_BULK_QUEUE_SIZE	16
> @@ -312,9 +311,9 @@ static inline void xdp_scrub_frame(struct xdp_frame *frame)
>   }
>   
>   static inline void
> -xdp_update_skb_shared_info(struct sk_buff *skb, u8 nr_frags,
> -			   unsigned int size, unsigned int truesize,
> -			   bool pfmemalloc)
> +xdp_update_skb_frags_info(struct sk_buff *skb, u8 nr_frags,
> +			  unsigned int size, unsigned int truesize,
> +			  u32 xdp_flags)
>   {
>   	struct skb_shared_info *sinfo = skb_shinfo(skb);
>   
> @@ -328,7 +327,7 @@ xdp_update_skb_shared_info(struct sk_buff *skb, u8 nr_frags,
>   	skb->len += size;
>   	skb->data_len += size;
>   	skb->truesize += truesize;
> -	skb->pfmemalloc |= pfmemalloc;
> +	skb->pfmemalloc |= !!(xdp_flags & XDP_FLAGS_FRAGS_PF_MEMALLOC);
>   }
>   
>   /* Avoids inlining WARN macro in fast-path */
> diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
> index 58d579dca3f1..3e77a96e5a3e 100644
> --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
> +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
> @@ -468,9 +468,8 @@ bnxt_xdp_build_skb(struct bnxt *bp, struct sk_buff *skb, u8 num_frags,
>   	if (!skb)
>   		return NULL;
>   
> -	xdp_update_skb_shared_info(skb, num_frags,
> -				   sinfo->xdp_frags_size,
> -				   BNXT_RX_PAGE_SIZE * num_frags,
> -				   xdp_buff_is_frag_pfmemalloc(xdp));
> +	xdp_update_skb_frags_info(skb, num_frags, sinfo->xdp_frags_size,
> +				  BNXT_RX_PAGE_SIZE * num_frags,
> +				  xdp_buff_get_skb_flags(xdp));
>   	return skb;
>   }
> diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
> index 048c33039130..98601c62c592 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
> +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
> @@ -2151,10 +2151,10 @@ static struct sk_buff *i40e_construct_skb(struct i40e_ring *rx_ring,
>   		memcpy(&skinfo->frags[skinfo->nr_frags], &sinfo->frags[0],
>   		       sizeof(skb_frag_t) * nr_frags);
>   
> -		xdp_update_skb_shared_info(skb, skinfo->nr_frags + nr_frags,
> -					   sinfo->xdp_frags_size,
> -					   nr_frags * xdp->frame_sz,
> -					   xdp_buff_is_frag_pfmemalloc(xdp));
> +		xdp_update_skb_frags_info(skb, skinfo->nr_frags + nr_frags,
> +					  sinfo->xdp_frags_size,
> +					  nr_frags * xdp->frame_sz,
> +					  xdp_buff_get_skb_flags(xdp));
>   
>   		/* First buffer has already been processed, so bump ntc */
>   		if (++rx_ring->next_to_clean == rx_ring->count)
> @@ -2206,10 +2206,9 @@ static struct sk_buff *i40e_build_skb(struct i40e_ring *rx_ring,
>   		skb_metadata_set(skb, metasize);
>   
>   	if (unlikely(xdp_buff_has_frags(xdp))) {
> -		xdp_update_skb_shared_info(skb, nr_frags,
> -					   sinfo->xdp_frags_size,
> -					   nr_frags * xdp->frame_sz,
> -					   xdp_buff_is_frag_pfmemalloc(xdp));
> +		xdp_update_skb_frags_info(skb, nr_frags, sinfo->xdp_frags_size,
> +					  nr_frags * xdp->frame_sz,
> +					  xdp_buff_get_skb_flags(xdp));
>   
>   		i40e_process_rx_buffs(rx_ring, I40E_XDP_PASS, xdp);
>   	} else {
> diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c
> index d2871757ec94..107632a71f3c 100644
> --- a/drivers/net/ethernet/intel/ice/ice_txrx.c
> +++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
> @@ -1035,10 +1035,9 @@ ice_build_skb(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp)
>   		skb_metadata_set(skb, metasize);
>   
>   	if (unlikely(xdp_buff_has_frags(xdp)))
> -		xdp_update_skb_shared_info(skb, nr_frags,
> -					   sinfo->xdp_frags_size,
> -					   nr_frags * xdp->frame_sz,
> -					   xdp_buff_is_frag_pfmemalloc(xdp));
> +		xdp_update_skb_frags_info(skb, nr_frags, sinfo->xdp_frags_size,
> +					  nr_frags * xdp->frame_sz,
> +					  xdp_buff_get_skb_flags(xdp));
>   
>   	return skb;
>   }
> @@ -1115,10 +1114,10 @@ ice_construct_skb(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp)
>   		memcpy(&skinfo->frags[skinfo->nr_frags], &sinfo->frags[0],
>   		       sizeof(skb_frag_t) * nr_frags);
>   
> -		xdp_update_skb_shared_info(skb, skinfo->nr_frags + nr_frags,
> -					   sinfo->xdp_frags_size,
> -					   nr_frags * xdp->frame_sz,
> -					   xdp_buff_is_frag_pfmemalloc(xdp));
> +		xdp_update_skb_frags_info(skb, skinfo->nr_frags + nr_frags,
> +					  sinfo->xdp_frags_size,
> +					  nr_frags * xdp->frame_sz,
> +					  xdp_buff_get_skb_flags(xdp));
>   	}
>   
>   	return skb;
> diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
> index 476e73e502fe..7351e98d73f4 100644
> --- a/drivers/net/ethernet/marvell/mvneta.c
> +++ b/drivers/net/ethernet/marvell/mvneta.c
> @@ -2416,10 +2416,9 @@ mvneta_swbm_build_skb(struct mvneta_port *pp, struct page_pool *pool,
>   	skb->ip_summed = mvneta_rx_csum(pp, desc_status);
>   
>   	if (unlikely(xdp_buff_has_frags(xdp)))
> -		xdp_update_skb_shared_info(skb, num_frags,
> -					   sinfo->xdp_frags_size,
> -					   num_frags * xdp->frame_sz,
> -					   xdp_buff_is_frag_pfmemalloc(xdp));
> +		xdp_update_skb_frags_info(skb, num_frags, sinfo->xdp_frags_size,
> +					  num_frags * xdp->frame_sz,
> +					  xdp_buff_get_skb_flags(xdp));
>   
>   	return skb;
>   }
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
> index b8c609d91d11..2925ece136c4 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
> @@ -1796,10 +1796,9 @@ mlx5e_skb_from_cqe_nonlinear(struct mlx5e_rq *rq, struct mlx5e_wqe_frag_info *wi
>   
>   	if (xdp_buff_has_frags(&mxbuf->xdp)) {
>   		/* sinfo->nr_frags is reset by build_skb, calculate again. */
> -		xdp_update_skb_shared_info(skb, wi - head_wi - 1,
> -					   sinfo->xdp_frags_size, truesize,
> -					   xdp_buff_is_frag_pfmemalloc(
> -						&mxbuf->xdp));
> +		xdp_update_skb_frags_info(skb, wi - head_wi - 1,
> +					  sinfo->xdp_frags_size, truesize,
> +					  xdp_buff_get_skb_flags(&mxbuf->xdp));
>   
>   		for (struct mlx5e_wqe_frag_info *pwi = head_wi + 1; pwi < wi; pwi++)
>   			pwi->frag_page->frags++;
> @@ -2105,10 +2104,10 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w
>   			struct mlx5e_frag_page *pagep;
>   
>   			/* sinfo->nr_frags is reset by build_skb, calculate again. */
> -			xdp_update_skb_shared_info(skb, frag_page - head_page,
> -						   sinfo->xdp_frags_size, truesize,
> -						   xdp_buff_is_frag_pfmemalloc(
> -							&mxbuf->xdp));
> +			xdp_update_skb_frags_info(skb, frag_page - head_page,
> +						  sinfo->xdp_frags_size,
> +						  truesize,
> +						  xdp_buff_get_skb_flags(&mxbuf->xdp));
>   
>   			pagep = head_page;
>   			do
> @@ -2122,10 +2121,10 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w
>   		if (xdp_buff_has_frags(&mxbuf->xdp)) {
>   			struct mlx5e_frag_page *pagep;
>   
> -			xdp_update_skb_shared_info(skb, sinfo->nr_frags,
> -						   sinfo->xdp_frags_size, truesize,
> -						   xdp_buff_is_frag_pfmemalloc(
> -							&mxbuf->xdp));
> +			xdp_update_skb_frags_info(skb, sinfo->nr_frags,
> +						  sinfo->xdp_frags_size,
> +						  truesize,
> +						  xdp_buff_get_skb_flags(&mxbuf->xdp));
>   
>   			pagep = frag_page - sinfo->nr_frags;
>   			do
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 975bdc5dab84..06708c9a979e 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -2185,10 +2185,9 @@ static struct sk_buff *build_skb_from_xdp_buff(struct net_device *dev,
>   		skb_metadata_set(skb, metasize);
>   
>   	if (unlikely(xdp_buff_has_frags(xdp)))
> -		xdp_update_skb_shared_info(skb, nr_frags,
> -					   sinfo->xdp_frags_size,
> -					   xdp_frags_truesz,
> -					   xdp_buff_is_frag_pfmemalloc(xdp));
> +		xdp_update_skb_frags_info(skb, nr_frags, sinfo->xdp_frags_size,
> +					  xdp_frags_truesz,
> +					  xdp_buff_get_skb_flags(xdp));
>   
>   	return skb;
>   }
> diff --git a/net/core/xdp.c b/net/core/xdp.c
> index 491334b9b8be..9100e160113a 100644
> --- a/net/core/xdp.c
> +++ b/net/core/xdp.c
> @@ -663,9 +663,8 @@ struct sk_buff *xdp_build_skb_from_buff(const struct xdp_buff *xdp)
>   		u32 tsize;
>   
>   		tsize = sinfo->xdp_frags_truesize ? : nr_frags * xdp->frame_sz;
> -		xdp_update_skb_shared_info(skb, nr_frags,
> -					   sinfo->xdp_frags_size, tsize,
> -					   xdp_buff_is_frag_pfmemalloc(xdp));
> +		xdp_update_skb_frags_info(skb, nr_frags, sinfo->xdp_frags_size,
> +					  tsize, xdp_buff_get_skb_flags(xdp));
>   	}
>   
>   	skb->protocol = eth_type_trans(skb, rxq->dev);
> @@ -692,7 +691,7 @@ static noinline bool xdp_copy_frags_from_zc(struct sk_buff *skb,
>   	struct skb_shared_info *sinfo = skb_shinfo(skb);
>   	const struct skb_shared_info *xinfo;
>   	u32 nr_frags, tsize = 0;
> -	bool pfmemalloc = false;
> +	u32 flags = 0;
>   
>   	xinfo = xdp_get_shared_info_from_buff(xdp);
>   	nr_frags = xinfo->nr_frags;
> @@ -714,11 +713,12 @@ static noinline bool xdp_copy_frags_from_zc(struct sk_buff *skb,
>   		__skb_fill_page_desc_noacc(sinfo, i, page, offset, len);
>   
>   		tsize += truesize;
> -		pfmemalloc |= page_is_pfmemalloc(page);
> +		if (page_is_pfmemalloc(page))
> +			flags |= XDP_FLAGS_FRAGS_PF_MEMALLOC;
>   	}
>   
> -	xdp_update_skb_shared_info(skb, nr_frags, xinfo->xdp_frags_size,
> -				   tsize, pfmemalloc);
> +	xdp_update_skb_frags_info(skb, nr_frags, xinfo->xdp_frags_size, tsize,
> +				  flags);
>   
>   	return true;
>   }
> @@ -823,10 +823,9 @@ struct sk_buff *__xdp_build_skb_from_frame(struct xdp_frame *xdpf,
>   		skb_metadata_set(skb, xdpf->metasize);
>   
>   	if (unlikely(xdp_frame_has_frags(xdpf)))
> -		xdp_update_skb_shared_info(skb, nr_frags,
> -					   sinfo->xdp_frags_size,
> -					   nr_frags * xdpf->frame_sz,
> -					   xdp_frame_is_frag_pfmemalloc(xdpf));
> +		xdp_update_skb_frags_info(skb, nr_frags, sinfo->xdp_frags_size,
> +					  nr_frags * xdpf->frame_sz,
> +					  xdp_frame_get_skb_flags(xdpf));
>   
>   	/* Essential SKB info: protocol and skb->dev */
>   	skb->protocol = eth_type_trans(skb, dev);


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next 1/2] net: xdp: pass full flags to xdp_update_skb_shared_info()
  2025-09-09 13:30   ` Jesper Dangaard Brouer
@ 2025-09-09 23:24     ` Jakub Kicinski
  0 siblings, 0 replies; 8+ messages in thread
From: Jakub Kicinski @ 2025-09-09 23:24 UTC (permalink / raw)
  To: Jesper Dangaard Brouer
  Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, daniel,
	john.fastabend, sdf, michael.chan, anthony.l.nguyen,
	marcin.s.wojtas, tariqt, mbloch, jasowang, bpf,
	aleksander.lobakin, pavan.chebbi, przemyslaw.kitszel

On Tue, 9 Sep 2025 15:30:00 +0200 Jesper Dangaard Brouer wrote:
> I'm fine with the name xdp_update_skb_frags_info().
> But I want to point out that the function *does* also update shinfo.
> The xdp_buff/xdp-frame have a compatible layout for shinfo, except for a
> union with sinfo->destructor_arg, which we need to clear.  This is a
> transition point from XDP to SKB, which is why I think the function name
> change is appropiate.

Fair point.
My initial confusion was because I expected xdp_update_skb_shared_info()
to _only_ update shinfo.

> > Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> > ---
> > v1:
> >   - rename skb_flags arg to xdp_flags  
> 
> Thanks for that. You kept the function name xdp_buff_get_skb_flags(),
> indicating this is "skb_flags". I don't think it matters much, so to
> avoid bikesheeting I'm just going to ACK this.

Thanks! Happy to respin with whatever names, if anyone expresses 
a strong opinion. Otherwise I'll fix the typo and apply tomorrow. 
Indeed the risk of bikeshedding is rather high here :)

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next 0/2] net: xdp: handle frags with unreadable memory
  2025-09-05 22:15 [PATCH net-next 0/2] net: xdp: handle frags with unreadable memory Jakub Kicinski
                   ` (3 preceding siblings ...)
  2025-09-08 12:02 ` Alexander Lobakin
@ 2025-09-11 10:10 ` patchwork-bot+netdevbpf
  4 siblings, 0 replies; 8+ messages in thread
From: patchwork-bot+netdevbpf @ 2025-09-11 10:10 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, daniel,
	hawk, john.fastabend, sdf, michael.chan, anthony.l.nguyen,
	marcin.s.wojtas, tariqt, mbloch, jasowang, bpf,
	aleksander.lobakin, pavan.chebbi, przemyslaw.kitszel

Hello:

This series was applied to netdev/net-next.git (main)
by Paolo Abeni <pabeni@redhat.com>:

On Fri,  5 Sep 2025 15:15:37 -0700 you wrote:
> Make XDP helpers compatible with unreadable memory. This is very
> similar to how we handle pfmemalloc frags today. Record the info
> in xdp_buf flags as frags get added and then update the skb once
> allocated.
> 
> This series adds the unreadable memory metadata tracking to drivers
> using xdp_build_skb_from*() with no changes on the driver side - hence
> the only driver changes here are refactoring. Obviously, unreadable memory
> is incompatible with XDP today, but thanks to xdp_build_skb_from_buf()
> increasing number of drivers have a unified datapath, whether XDP is
> enabled or not.
> 
> [...]

Here is the summary with links:
  - [net-next,1/2] net: xdp: pass full flags to xdp_update_skb_shared_info()
    https://git.kernel.org/netdev/net-next/c/1827f773e416
  - [net-next,2/2] net: xdp: handle frags with unreadable memory
    https://git.kernel.org/netdev/net-next/c/6bffdc0f88f8

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2025-09-11 10:10 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-05 22:15 [PATCH net-next 0/2] net: xdp: handle frags with unreadable memory Jakub Kicinski
2025-09-05 22:15 ` [PATCH net-next 1/2] net: xdp: pass full flags to xdp_update_skb_shared_info() Jakub Kicinski
2025-09-09 13:30   ` Jesper Dangaard Brouer
2025-09-09 23:24     ` Jakub Kicinski
2025-09-05 22:15 ` [PATCH net-next 2/2] net: xdp: handle frags with unreadable memory Jakub Kicinski
2025-09-05 22:55 ` [PATCH net-next 0/2] " Stanislav Fomichev
2025-09-08 12:02 ` Alexander Lobakin
2025-09-11 10:10 ` patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).