tap = rcu_dereference(q->tap);
        /* copy skb_ubuf_info for callback when skb has no error */
        if (zerocopy) {
-               skb_shinfo(skb)->destructor_arg = msg_control;
-               skb_shinfo(skb)->flags |= SKBFL_ZEROCOPY_FRAG;
+               skb_zcopy_init(skb, msg_control);
        } else if (msg_control) {
                struct ubuf_info *uarg = msg_control;
                uarg->callback(NULL, uarg, false);
 
 
        /* copy skb_ubuf_info for callback when skb has no error */
        if (zerocopy) {
-               skb_shinfo(skb)->destructor_arg = msg_control;
-               skb_shinfo(skb)->flags |= SKBFL_ZEROCOPY_FRAG;
+               skb_zcopy_init(skb, msg_control);
        } else if (msg_control) {
                struct ubuf_info *uarg = msg_control;
                uarg->callback(NULL, uarg, false);
 
                        ubuf->callback = vhost_zerocopy_callback;
                        ubuf->ctx = nvq->ubufs;
                        ubuf->desc = nvq->upend_idx;
+                       ubuf->flags = SKBFL_ZEROCOPY_FRAG;
                        refcount_set(&ubuf->refcnt, 1);
                        msg.msg_control = &ctl;
                        ctl.type = TUN_MSG_UBUF;
 
        refcount_inc(&uarg->refcnt);
 }
 
+static inline void skb_zcopy_init(struct sk_buff *skb, struct ubuf_info *uarg)
+{
+       skb_shinfo(skb)->destructor_arg = uarg;
+       skb_shinfo(skb)->flags |= uarg->flags;
+}
+
 static inline void skb_zcopy_set(struct sk_buff *skb, struct ubuf_info *uarg,
                                 bool *have_ref)
 {
                        *have_ref = false;
                else
                        skb_zcopy_get(uarg);
-               skb_shinfo(skb)->destructor_arg = uarg;
-               skb_shinfo(skb)->flags |= uarg->flags;
+               skb_zcopy_init(skb, uarg);
        }
 }