From: Jonathan Lemon <b...@fb.com>

In preparation for further work, the zcopy* routines will
become basic building blocks, while the zerocopy* ones will
be specific for the existing zerocopy implementation.

All uargs should have a callback function, (unless nouarg
is set), so push all special case logic handling down into
the callbacks.  This slightly pessimizes the refcounted cases,
but makes the skb_zcopy_*() routines clearer.

Signed-off-by: Jonathan Lemon <jonathan.le...@gmail.com>
---
 include/linux/skbuff.h | 19 +++++++++----------
 net/core/skbuff.c      | 21 +++++++++------------
 net/ipv4/tcp.c         |  2 +-
 3 files changed, 19 insertions(+), 23 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index fb6dd6af0f82..df98d61e8c51 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -499,7 +499,6 @@ static inline void sock_zerocopy_get(struct ubuf_info *uarg)
        refcount_inc(&uarg->refcnt);
 }
 
-void sock_zerocopy_put(struct ubuf_info *uarg);
 void sock_zerocopy_put_abort(struct ubuf_info *uarg, bool have_uref);
 
 void sock_zerocopy_callback(struct ubuf_info *uarg, bool success);
@@ -1474,20 +1473,20 @@ static inline void *skb_zcopy_get_nouarg(struct sk_buff 
*skb)
        return (void *)((uintptr_t) skb_shinfo(skb)->destructor_arg & ~0x1UL);
 }
 
+static inline void skb_zcopy_put(struct ubuf_info *uarg)
+{
+       if (uarg)
+               uarg->callback(uarg, true);
+}
+
 /* Release a reference on a zerocopy structure */
-static inline void skb_zcopy_clear(struct sk_buff *skb, bool zerocopy)
+static inline void skb_zcopy_clear(struct sk_buff *skb, bool succsss)
 {
        struct ubuf_info *uarg = skb_zcopy(skb);
 
        if (uarg) {
-               if (skb_zcopy_is_nouarg(skb)) {
-                       /* no notification callback */
-               } else if (uarg->callback == sock_zerocopy_callback) {
-                       uarg->zerocopy = uarg->zerocopy && zerocopy;
-                       sock_zerocopy_put(uarg);
-               } else {
-                       uarg->callback(uarg, zerocopy);
-               }
+               if (!skb_zcopy_is_nouarg(skb))
+                       uarg->callback(uarg, succsss);
 
                skb_shinfo(skb)->zc_flags &= ~SKBZC_FRAGMENTS;
        }
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 327ee8938f78..984760dd670b 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,18 +1241,15 @@ void sock_zerocopy_callback(struct ubuf_info *uarg, 
bool success)
        consume_skb(skb);
        sock_put(sk);
 }
-EXPORT_SYMBOL_GPL(sock_zerocopy_callback);
 
-void sock_zerocopy_put(struct ubuf_info *uarg)
+void sock_zerocopy_callback(struct ubuf_info *uarg, bool success)
 {
-       if (uarg && refcount_dec_and_test(&uarg->refcnt)) {
-               if (uarg->callback)
-                       uarg->callback(uarg, uarg->zerocopy);
-               else
-                       consume_skb(skb_from_uarg(uarg));
-       }
+       uarg->zerocopy = uarg->zerocopy & success;
+
+       if (refcount_dec_and_test(&uarg->refcnt))
+               __sock_zerocopy_callback(uarg);
 }
-EXPORT_SYMBOL_GPL(sock_zerocopy_put);
+EXPORT_SYMBOL_GPL(sock_zerocopy_callback);
 
 void sock_zerocopy_put_abort(struct ubuf_info *uarg, bool have_uref)
 {
@@ -1263,7 +1260,7 @@ void sock_zerocopy_put_abort(struct ubuf_info *uarg, bool 
have_uref)
                uarg->len--;
 
                if (have_uref)
-                       sock_zerocopy_put(uarg);
+                       skb_zcopy_put(uarg);
        }
 }
 EXPORT_SYMBOL_GPL(sock_zerocopy_put_abort);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index fea9bae370e4..5c38080df13f 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1429,7 +1429,7 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr 
*msg, size_t size)
                tcp_push(sk, flags, mss_now, tp->nonagle, size_goal);
        }
 out_nopush:
-       sock_zerocopy_put(uarg);
+       skb_zcopy_put(uarg);
        return copied + copied_syn;
 
 do_error:
-- 
2.24.1

Reply via email to