skbuff: Call sock_zerocopy_put_abort from skb_zcopy_put_abort
authorJonathan Lemon <jonathan.lemon@gmail.com>
Wed, 6 Jan 2021 22:18:35 +0000 (14:18 -0800)
committerJakub Kicinski <kuba@kernel.org>
Fri, 8 Jan 2021 00:06:37 +0000 (16:06 -0800)
The sock_zerocopy_put_abort function contains logic which is
specific to the current zerocopy implementation.  Add a wrapper
which checks the callback and dispatches apppropriately.

Signed-off-by: Jonathan Lemon <jonathan.lemon@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
include/linux/skbuff.h
net/core/skbuff.c
net/ipv4/ip_output.c
net/ipv4/tcp.c
net/ipv6/ip6_output.c

index b23c3b4b32095508280b9198b4b85f9d3472b0e6..9f7393167f0abb9d4b599a0f80d67c1048e2e6aa 100644 (file)
@@ -1478,6 +1478,16 @@ static inline void skb_zcopy_put(struct ubuf_info *uarg)
                uarg->callback(NULL, uarg, true);
 }
 
+static inline void skb_zcopy_put_abort(struct ubuf_info *uarg, bool have_uref)
+{
+       if (uarg) {
+               if (uarg->callback == sock_zerocopy_callback)
+                       sock_zerocopy_put_abort(uarg, have_uref);
+               else if (have_uref)
+                       skb_zcopy_put(uarg);
+       }
+}
+
 /* Release a reference on a zerocopy structure */
 static inline void skb_zcopy_clear(struct sk_buff *skb, bool zerocopy_success)
 {
index 89130b21d9f0e07320efce219ebb50ba54ccf0ca..5b9cd528d6a64448f69b33c134d230d354b9fb38 100644 (file)
@@ -1254,15 +1254,13 @@ EXPORT_SYMBOL_GPL(sock_zerocopy_callback);
 
 void sock_zerocopy_put_abort(struct ubuf_info *uarg, bool have_uref)
 {
-       if (uarg) {
-               struct sock *sk = skb_from_uarg(uarg)->sk;
+       struct sock *sk = skb_from_uarg(uarg)->sk;
 
-               atomic_dec(&sk->sk_zckey);
-               uarg->len--;
+       atomic_dec(&sk->sk_zckey);
+       uarg->len--;
 
-               if (have_uref)
-                       skb_zcopy_put(uarg);
-       }
+       if (have_uref)
+               sock_zerocopy_callback(NULL, uarg, true);
 }
 EXPORT_SYMBOL_GPL(sock_zerocopy_put_abort);
 
index 89fff5f59eea441c1b016a4576aa3c4e5a204935..bae9b29e17a3b7a20c1dfcb2b448f3046a4a7584 100644 (file)
@@ -1230,8 +1230,7 @@ alloc_new_skb:
 error_efault:
        err = -EFAULT;
 error:
-       if (uarg)
-               sock_zerocopy_put_abort(uarg, extra_uref);
+       skb_zcopy_put_abort(uarg, extra_uref);
        cork->length -= length;
        IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTDISCARDS);
        refcount_add(wmem_alloc_delta, &sk->sk_wmem_alloc);
index 298a1fae841c9fcb4cabfc3913fad02e972c8877..fb58215972ba9b63985157064f4a5a5059012baf 100644 (file)
@@ -1440,7 +1440,7 @@ do_fault:
        if (copied + copied_syn)
                goto out;
 out_err:
-       sock_zerocopy_put_abort(uarg, true);
+       skb_zcopy_put_abort(uarg, true);
        err = sk_stream_error(sk, flags, err);
        /* make sure we wake any epoll edge trigger waiter */
        if (unlikely(tcp_rtx_and_write_queues_empty(sk) && err == -EAGAIN)) {
index 749ad72386b232183315d43ab12efc9b90e841f8..c8c87891533a44399ee61bad059e318ca6147bb5 100644 (file)
@@ -1715,8 +1715,7 @@ alloc_new_skb:
 error_efault:
        err = -EFAULT;
 error:
-       if (uarg)
-               sock_zerocopy_put_abort(uarg, extra_uref);
+       skb_zcopy_put_abort(uarg, extra_uref);
        cork->length -= length;
        IP6_INC_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS);
        refcount_add(wmem_alloc_delta, &sk->sk_wmem_alloc);