Thread (31 messages) 31 messages, 6 authors, 2025-08-29

Re: [PATCH net-next v2 4/9] xsk: extend xsk_build_skb() to support passing an already allocated skb

From: Jason Xing <hidden>
Date: 2025-08-26 00:27:18
Also in: bpf

On Tue, Aug 26, 2025 at 5:49 AM Maciej Fijalkowski
[off-list ref] wrote:
On Mon, Aug 25, 2025 at 09:53:37PM +0800, Jason Xing wrote:
quoted
From: Jason Xing <kernelxing@tencent.com>

Batch xmit mode needs to allocate and build skbs at one time. To avoid
reinvent the wheel, use xsk_build_skb() as the second half process of
the whole initialization of each skb.

The original xsk_build_skb() itself allocates a new skb by calling
sock_alloc_send_skb whether in copy mode or zerocopy mode. Add a new
parameter allocated skb to let other callers to pass an already
allocated skb to support later xmit batch feature. At that time,
another building skb function will generate a new skb and pass it to
xsk_build_skb() to finish the rest of building process, like
initializing structures and copying data.
are you saying you were able to avoid sock_alloc_send_skb() calls for
batching approach and your socket memory accounting problems disappeared?
IIUC, memory accounting is needed because it keeps safe for xsk [1].

The above description says I reused part of xsk_build_skb() in the
batching process.

[1]: https://lore.kernel.org/all/CAL+tcoBvLHFJJuYawJc3wY2aOrn5CQ3s5+sbC2M24_QNLyBHsg@mail.gmail.com/ (local)
quoted
Signed-off-by: Jason Xing <kernelxing@tencent.com>
---
 include/net/xdp_sock.h |  4 ++++
 net/xdp/xsk.c          | 23 ++++++++++++++++-------
 2 files changed, 20 insertions(+), 7 deletions(-)
diff --git a/include/net/xdp_sock.h b/include/net/xdp_sock.h
index c2b05268b8ad..cbba880c27c3 100644
--- a/include/net/xdp_sock.h
+++ b/include/net/xdp_sock.h
@@ -123,6 +123,10 @@ struct xsk_tx_metadata_ops {
      void    (*tmo_request_launch_time)(u64 launch_time, void *priv);
 };

+
+struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
+                           struct sk_buff *allocated_skb,
+                           struct xdp_desc *desc);
why do you export this?
Because patch 5 needs this in xsk_alloc_batch_skb().

Thanks,
Jason
quoted
 #ifdef CONFIG_XDP_SOCKETS

 int xsk_generic_rcv(struct xdp_sock *xs, struct xdp_buff *xdp);
diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
index 173ad49379c3..213d6100e405 100644
--- a/net/xdp/xsk.c
+++ b/net/xdp/xsk.c
@@ -605,6 +605,7 @@ static void xsk_drop_skb(struct sk_buff *skb)
 }

 static struct sk_buff *xsk_build_skb_zerocopy(struct xdp_sock *xs,
+                                           struct sk_buff *allocated_skb,
                                            struct xdp_desc *desc)
 {
      struct xsk_buff_pool *pool = xs->pool;
@@ -618,7 +619,10 @@ static struct sk_buff *xsk_build_skb_zerocopy(struct xdp_sock *xs,
      if (!skb) {
              hr = max(NET_SKB_PAD, L1_CACHE_ALIGN(xs->dev->needed_headroom));

-             skb = sock_alloc_send_skb(&xs->sk, hr, 1, &err);
+             if (!allocated_skb)
+                     skb = sock_alloc_send_skb(&xs->sk, hr, 1, &err);
+             else
+                     skb = allocated_skb;
              if (unlikely(!skb))
                      return ERR_PTR(err);
@@ -657,8 +661,9 @@ static struct sk_buff *xsk_build_skb_zerocopy(struct xdp_sock *xs,
      return skb;
 }

-static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
-                                  struct xdp_desc *desc)
+struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
+                           struct sk_buff *allocated_skb,
+                           struct xdp_desc *desc)
 {
      struct xsk_tx_metadata *meta = NULL;
      struct net_device *dev = xs->dev;
@@ -667,7 +672,7 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
      int err;

      if (dev->priv_flags & IFF_TX_SKB_NO_LINEAR) {
-             skb = xsk_build_skb_zerocopy(xs, desc);
+             skb = xsk_build_skb_zerocopy(xs, allocated_skb, desc);
              if (IS_ERR(skb)) {
                      err = PTR_ERR(skb);
                      goto free_err;
@@ -683,8 +688,12 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
                      first_frag = true;

                      hr = max(NET_SKB_PAD, L1_CACHE_ALIGN(dev->needed_headroom));
-                     tr = dev->needed_tailroom;
-                     skb = sock_alloc_send_skb(&xs->sk, hr + len + tr, 1, &err);
+                     if (!allocated_skb) {
+                             tr = dev->needed_tailroom;
+                             skb = sock_alloc_send_skb(&xs->sk, hr + len + tr, 1, &err);
+                     } else {
+                             skb = allocated_skb;
+                     }
                      if (unlikely(!skb))
                              goto free_err;
@@ -818,7 +827,7 @@ static int __xsk_generic_xmit(struct sock *sk)
                      goto out;
              }

-             skb = xsk_build_skb(xs, &desc);
+             skb = xsk_build_skb(xs, NULL, &desc);
              if (IS_ERR(skb)) {
                      err = PTR_ERR(skb);
                      if (err != -EOVERFLOW)
--
2.41.3
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help