]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
xsk: avoid overwriting skb fields for multi-buffer traffic
authorMaciej Fijalkowski <maciej.fijalkowski@intel.com>
Thu, 25 Sep 2025 16:00:07 +0000 (18:00 +0200)
committerJakub Kicinski <kuba@kernel.org>
Fri, 26 Sep 2025 20:51:45 +0000 (13:51 -0700)
We are unnecessarily setting a bunch of skb fields per each processed
descriptor, which is redundant for fragmented frames.

Let us set these respective members for first fragment only. To address
both paths that we have within xsk_build_skb(), move assignments onto
xsk_set_destructor_arg() and rename it to xsk_skb_init_misc().

Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>
Acked-by: Martin KaFai Lau <martin.lau@kernel.org>
Link: https://patch.msgid.link/20250925160009.2474816-2-maciej.fijalkowski@intel.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/xdp/xsk.c

index 72e34bd2d925c0197dc1c78d4f52059016f7db0b..01f258894faebb968bb2ae8509173674d37941bf 100644 (file)
@@ -618,11 +618,16 @@ static void xsk_destruct_skb(struct sk_buff *skb)
        sock_wfree(skb);
 }
 
-static void xsk_set_destructor_arg(struct sk_buff *skb, u64 addr)
+static void xsk_skb_init_misc(struct sk_buff *skb, struct xdp_sock *xs,
+                             u64 addr)
 {
        BUILD_BUG_ON(sizeof(struct xsk_addr_head) > sizeof(skb->cb));
        INIT_LIST_HEAD(&XSKCB(skb)->addrs_list);
+       skb->dev = xs->dev;
+       skb->priority = READ_ONCE(xs->sk.sk_priority);
+       skb->mark = READ_ONCE(xs->sk.sk_mark);
        XSKCB(skb)->num_descs = 0;
+       skb->destructor = xsk_destruct_skb;
        skb_shinfo(skb)->destructor_arg = (void *)(uintptr_t)addr;
 }
 
@@ -673,7 +678,7 @@ static struct sk_buff *xsk_build_skb_zerocopy(struct xdp_sock *xs,
 
                skb_reserve(skb, hr);
 
-               xsk_set_destructor_arg(skb, desc->addr);
+               xsk_skb_init_misc(skb, xs, desc->addr);
        } else {
                xsk_addr = kmem_cache_zalloc(xsk_tx_generic_cache, GFP_KERNEL);
                if (!xsk_addr)
@@ -757,7 +762,7 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
                        if (unlikely(err))
                                goto free_err;
 
-                       xsk_set_destructor_arg(skb, desc->addr);
+                       xsk_skb_init_misc(skb, xs, desc->addr);
                } else {
                        int nr_frags = skb_shinfo(skb)->nr_frags;
                        struct xsk_addr_node *xsk_addr;
@@ -826,14 +831,10 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
 
                        if (meta->flags & XDP_TXMD_FLAGS_LAUNCH_TIME)
                                skb->skb_mstamp_ns = meta->request.launch_time;
+                       xsk_tx_metadata_to_compl(meta, &skb_shinfo(skb)->xsk_meta);
                }
        }
 
-       skb->dev = dev;
-       skb->priority = READ_ONCE(xs->sk.sk_priority);
-       skb->mark = READ_ONCE(xs->sk.sk_mark);
-       skb->destructor = xsk_destruct_skb;
-       xsk_tx_metadata_to_compl(meta, &skb_shinfo(skb)->xsk_meta);
        xsk_inc_num_desc(skb);
 
        return skb;