[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20231107214045.2172393-9-dw@davidwei.uk>
Date: Tue, 7 Nov 2023 13:40:33 -0800
From: David Wei <dw@...idwei.uk>
To: io-uring@...r.kernel.org,
netdev@...r.kernel.org
Cc: Jens Axboe <axboe@...nel.dk>,
Pavel Begunkov <asml.silence@...il.com>,
Jakub Kicinski <kuba@...nel.org>,
Paolo Abeni <pabeni@...hat.com>,
"David S. Miller" <davem@...emloft.net>,
Eric Dumazet <edumazet@...gle.com>,
Jesper Dangaard Brouer <hawk@...nel.org>,
David Ahern <dsahern@...nel.org>,
Mina Almasry <almasrymina@...gle.com>,
Willem de Bruijn <willemdebruijn.kernel@...il.com>,
Dragos Tatulea <dtatulea@...dia.com>
Subject: [PATCH 08/20] skbuff: add SKBFL_FIXED_FRAG and skb_fixed()
When an skb that is marked as zero copy goes up the network stack during
RX, skb_orphan_frags_rx is called which then calls skb_copy_ubufs and
defeat the purpose of ZC.
This is because currently zero copy is only for TX and this behaviour is
designed to prevent TX zero copy data being redirected up the network
stack rather than new zero copy RX data coming from the driver.
This patch adds a new flag SKBFL_FIXED_FRAG and checks for this in
skb_orphan_frags, not calling skb_copy_ubufs if it is set.
Co-developed-by: Pavel Begunkov <asml.silence@...il.com>
Signed-off-by: Pavel Begunkov <asml.silence@...il.com>
Signed-off-by: David Wei <dw@...idwei.uk>
---
include/linux/skbuff.h | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 4174c4b82d13..12de269d6827 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -516,6 +516,9 @@ enum {
* use frags only up until ubuf_info is released
*/
SKBFL_MANAGED_FRAG_REFS = BIT(4),
+
+ /* don't move or copy the fragment */
+ SKBFL_FIXED_FRAG = BIT(5),
};
#define SKBFL_ZEROCOPY_FRAG (SKBFL_ZEROCOPY_ENABLE | SKBFL_SHARED_FRAG)
@@ -1682,6 +1685,11 @@ static inline bool skb_zcopy_managed(const struct sk_buff *skb)
return skb_shinfo(skb)->flags & SKBFL_MANAGED_FRAG_REFS;
}
+static inline bool skb_fixed(const struct sk_buff *skb)
+{
+ return skb_shinfo(skb)->flags & SKBFL_FIXED_FRAG;
+}
+
static inline bool skb_pure_zcopy_same(const struct sk_buff *skb1,
const struct sk_buff *skb2)
{
@@ -3143,7 +3151,7 @@ static inline int skb_orphan_frags(struct sk_buff *skb, gfp_t gfp_mask)
/* Frags must be orphaned, even if refcounted, if skb might loop to rx path */
static inline int skb_orphan_frags_rx(struct sk_buff *skb, gfp_t gfp_mask)
{
- if (likely(!skb_zcopy(skb)))
+ if (likely(!skb_zcopy(skb) || skb_fixed(skb)))
return 0;
return skb_copy_ubufs(skb, gfp_mask);
}
--
2.39.3
Powered by blists - more mailing lists