]> www.infradead.org Git - users/hch/misc.git/commitdiff
net: xdp: pass full flags to xdp_update_skb_shared_info()
authorJakub Kicinski <kuba@kernel.org>
Fri, 5 Sep 2025 22:15:38 +0000 (15:15 -0700)
committerPaolo Abeni <pabeni@redhat.com>
Thu, 11 Sep 2025 10:00:20 +0000 (12:00 +0200)
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>
Acked-by: Jesper Dangaard Brouer <hawk@kernel.org>
Link: https://patch.msgid.link/20250905221539.2930285-2-kuba@kernel.org
Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Reviewed-by: Alexander Lobakin <aleksander.lobakin@intel.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
drivers/net/ethernet/intel/i40e/i40e_txrx.c
drivers/net/ethernet/intel/ice/ice_txrx.c
drivers/net/ethernet/marvell/mvneta.c
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
drivers/net/virtio_net.c
include/net/xdp.h
net/core/xdp.c

index 58d579dca3f194754723392a935b2556e22ae750..3e77a96e5a3e3970ecf46c8a1cbe4c2d2e6e696b 100644 (file)
@@ -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;
 }
index 048c3303913094f0a7b97e8f36ea0dd640f0dc69..98601c62c592d22046daa127b68af3bfd528e492 100644 (file)
@@ -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 {
index d2871757ec94012533e990e4bc208b1b2a82df2f..107632a71f3ca5536892b049ca4d934569d9c814 100644 (file)
@@ -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;
index 476e73e502fe9e174bd9566344a5914444cd45f3..7351e98d73f41017b508dc26fc9562e9738fae09 100644 (file)
@@ -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;
 }
index b8c609d91d11bd315e8fb67f794a91bd37cd28c0..2925ece136c4060eccaf5bde218b615e156cecd3 100644 (file)
@@ -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
index 975bdc5dab84b52113301eff0ed1a19e8e9de76d..06708c9a979e624d33d2290d1ec7e01b169ec3a6 100644 (file)
@@ -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;
 }
index af60e11b336cebb80f48efbaa9fe0ecc5e5adc00..976cfd2f113cd354edec92053fca36e369e4e307 100644 (file)
@@ -116,15 +116,14 @@ 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)
+static __always_inline void xdp_buff_set_frag_pfmemalloc(struct xdp_buff *xdp)
 {
-       return !!(xdp->flags & XDP_FLAGS_FRAGS_PF_MEMALLOC);
+       xdp->flags |= XDP_FLAGS_FRAGS_PF_MEMALLOC;
 }
 
-static __always_inline void xdp_buff_set_frag_pfmemalloc(struct xdp_buff *xdp)
+static __always_inline u32 xdp_buff_get_skb_flags(const struct xdp_buff *xdp)
 {
-       xdp->flags |= XDP_FLAGS_FRAGS_PF_MEMALLOC;
+       return xdp->flags;
 }
 
 static __always_inline void
@@ -294,10 +293,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
@@ -334,9 +333,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);
 
@@ -350,7 +349,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 */
index 491334b9b8beca9d99b9834d2b614ca8aa14c9ac..9100e160113a9a1e2cb88e7602e85c5f36a9f3b9 100644 (file)
@@ -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);