summaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorJonathan Lemon <jonathan.lemon@gmail.com>2021-01-06 14:18:31 -0800
committerJakub Kicinski <kuba@kernel.org>2021-01-07 16:06:37 -0800
commit75518851a2a0c047def521aaf87db401de098352 (patch)
treea167f12c49f067eeb0ddd7f0a8836b2d36b8fc56 /net/core
parentd6adf1b103bfe264a494c770f27fe985ab67202c (diff)
downloadlinux-75518851a2a0c047def521aaf87db401de098352.tar.bz2
skbuff: Push status and refcounts into sock_zerocopy_callback
Before this change, the caller of sock_zerocopy_callback would need to save the zerocopy status, decrement and check the refcount, and then call the callback function - the callback was only invoked when the refcount reached zero. Now, the caller just passes the status into the callback function, which saves the status and handles its own refcounts. This makes the behavior of the sock_zerocopy_callback identical to the tpacket and vhost callbacks. Signed-off-by: Jonathan Lemon <jonathan.lemon@gmail.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/skbuff.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index d88963f47f7d..8c18940723ff 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -1194,7 +1194,7 @@ static bool skb_zerocopy_notify_extend(struct sk_buff *skb, u32 lo, u16 len)
return true;
}
-void sock_zerocopy_callback(struct ubuf_info *uarg, bool success)
+static void __sock_zerocopy_callback(struct ubuf_info *uarg)
{
struct sk_buff *tail, *skb = skb_from_uarg(uarg);
struct sock_exterr_skb *serr;
@@ -1222,7 +1222,7 @@ void sock_zerocopy_callback(struct ubuf_info *uarg, bool success)
serr->ee.ee_origin = SO_EE_ORIGIN_ZEROCOPY;
serr->ee.ee_data = hi;
serr->ee.ee_info = lo;
- if (!success)
+ if (!uarg->zerocopy)
serr->ee.ee_code |= SO_EE_CODE_ZEROCOPY_COPIED;
q = &sk->sk_error_queue;
@@ -1241,11 +1241,19 @@ release:
consume_skb(skb);
sock_put(sk);
}
+
+void sock_zerocopy_callback(struct ubuf_info *uarg, bool success)
+{
+ uarg->zerocopy = uarg->zerocopy & success;
+
+ if (refcount_dec_and_test(&uarg->refcnt))
+ __sock_zerocopy_callback(uarg);
+}
EXPORT_SYMBOL_GPL(sock_zerocopy_callback);
void sock_zerocopy_put(struct ubuf_info *uarg)
{
- if (uarg && refcount_dec_and_test(&uarg->refcnt))
+ if (uarg)
uarg->callback(uarg, uarg->zerocopy);
}
EXPORT_SYMBOL_GPL(sock_zerocopy_put);