[PATCH v1 09/15] skbuff: Introduce SKBFL_FIXED_FRAG and skb_fixed()

Jonathan Lemon
2022-11-08T05:05:50Z

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 --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);
}
--
2.30.2