Re: [PATCH net-next v3 RFC] skb_expand_head() adjust skb->truesize incorrectly
From: Vasily Averin <hidden>
Date: 2021-09-01 06:20:41
Also in:
lkml
On 8/31/21 10:38 PM, Eric Dumazet wrote:
On 8/31/21 7:34 AM, Vasily Averin wrote:quoted
RFC because it have an extra changes: new is_skb_wmem() helper can be called - either before pskb_expand_head(), to create skb clones for skb with destructors that does not change sk->sk_wmem_alloc - or after pskb_expand_head(), to change owner in skb_set_owner_w() In current patch I've added both these ways, we need to keep one of them.
If nobody object I vote for 2nd way:
quoted
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index f931176..3ce33f2 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c@@ -1804,30 +1804,47 @@ struct sk_buff *skb_realloc_headroom(struct sk_buff *skb, unsigned int headroom) struct sk_buff *skb_expand_head(struct sk_buff *skb, unsigned int headroom) {
... skipped ...
quoted
- return skb; + if (oskb) { + if (sk) + skb_set_owner_w(skb, sk);Broken for non full sockets. Calling skb_set_owner_w(skb, sk) for them is a bug.
I think you're wrong here. It is 100% equivalent of old code, skb_set_owner_w() handles sk_fullsock(sk) inside and does not adjust sk->sk_wmem_alloc. Please explain if I'm wrong.
quoted
+ consume_skb(oskb); + } else if (sk) { + delta = osize - skb_end_offset(skb); + if (!is_skb_wmem(skb)) + skb_set_owner_w(skb, sk);This would be broken for non full sockets. Calling skb_set_owner_w(skb, sk) for them is a bug.
See my comment above.
quoted
+ skb->truesize += delta; + if (sk_fullsock(sk)) + refcount_add(delta, &sk->sk_wmem_alloc);quoted
+ } return skb;
Strange line, will fix it.
quoted
} EXPORT_SYMBOL(skb_expand_head);