diff mbox series

[RFC,v3,09/15] skbuff: Introduce SKBFL_FIXED_FRAG and skb_fixed()

Message ID 20221102233244.4022405-10-jonathan.lemon@gmail.com (mailing list archive)
State New
Headers show
Series zero-copy RX for io_uring | expand

Commit Message

Jonathan Lemon Nov. 2, 2022, 11:32 p.m. UTC
When a skb marked as zerocopy goes up the network stack, during
RX, it calls skb_orphan_frags_rx.  This is designed to catch TX
zerocopy data being redirected back up the stack, not new zerocopy
fragments coming up from the driver.

Currently, since the skb is marked as zerocopy, skb_copy_ubufs()
is called, defeating the point of zerocopy-RX.

Have the driver mark the fragments as fixed, so they are not copied.

Signed-off-by: Jonathan Lemon <jonathan.lemon@gmail.com>
---
 include/linux/skbuff.h | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 59c9fd55699d..5d57e2c37529 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)
@@ -1653,6 +1656,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)
 {
@@ -3089,7 +3097,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);
 }