diff options
-rw-r--r-- | include/linux/skbuff.h | 9 | ||||
-rw-r--r-- | net/core/skbuff.c | 4 |
2 files changed, 9 insertions, 4 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 8c0708d2e5e6..7594e19bce62 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1273,8 +1273,13 @@ static inline void skb_zcopy_clear(struct sk_buff *skb, bool zerocopy) struct ubuf_info *uarg = skb_zcopy(skb); if (uarg) { - uarg->zerocopy = uarg->zerocopy && zerocopy; - sock_zerocopy_put(uarg); + if (uarg->callback == sock_zerocopy_callback) { + uarg->zerocopy = uarg->zerocopy && zerocopy; + sock_zerocopy_put(uarg); + } else { + uarg->callback(uarg, zerocopy); + } + skb_shinfo(skb)->tx_flags &= ~SKBTX_ZEROCOPY_FRAG; } } diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 42b62c716a33..cb123590c674 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -1044,6 +1044,8 @@ void sock_zerocopy_callback(struct ubuf_info *uarg, bool success) u32 lo, hi; u16 len; + mm_unaccount_pinned_pages(&uarg->mmp); + /* if !len, there was only 1 call, and it was aborted * so do not queue a completion notification */ @@ -1084,8 +1086,6 @@ EXPORT_SYMBOL_GPL(sock_zerocopy_callback); void sock_zerocopy_put(struct ubuf_info *uarg) { if (uarg && atomic_dec_and_test(&uarg->refcnt)) { - mm_unaccount_pinned_pages(&uarg->mmp); - if (uarg->callback) uarg->callback(uarg, uarg->zerocopy); else |