@@ -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);
}
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(-)