Commit 36177832 authored by Jonathan Lemon's avatar Jonathan Lemon Committed by Jakub Kicinski

skbuff: Add skb parameter to the ubuf zerocopy callback

Add an optional skb parameter to the zerocopy callback parameter,
which is passed down from skb_zcopy_clear().  This gives access
to the original skb, which is needed for upcoming RX zero-copy
error handling.
Signed-off-by: default avatarJonathan Lemon <jonathan.lemon@gmail.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent e76d46cf
...@@ -727,7 +727,7 @@ static ssize_t tap_get_user(struct tap_queue *q, void *msg_control, ...@@ -727,7 +727,7 @@ static ssize_t tap_get_user(struct tap_queue *q, void *msg_control,
skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG; skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG;
} else if (msg_control) { } else if (msg_control) {
struct ubuf_info *uarg = msg_control; struct ubuf_info *uarg = msg_control;
uarg->callback(uarg, false); uarg->callback(NULL, uarg, false);
} }
if (tap) { if (tap) {
......
...@@ -1819,7 +1819,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, ...@@ -1819,7 +1819,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG; skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG;
} else if (msg_control) { } else if (msg_control) {
struct ubuf_info *uarg = msg_control; struct ubuf_info *uarg = msg_control;
uarg->callback(uarg, false); uarg->callback(NULL, uarg, false);
} }
skb_reset_network_header(skb); skb_reset_network_header(skb);
......
...@@ -399,7 +399,8 @@ void xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb); ...@@ -399,7 +399,8 @@ void xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb);
void xenvif_carrier_on(struct xenvif *vif); void xenvif_carrier_on(struct xenvif *vif);
/* Callback from stack when TX packet can be released */ /* Callback from stack when TX packet can be released */
void xenvif_zerocopy_callback(struct ubuf_info *ubuf, bool zerocopy_success); void xenvif_zerocopy_callback(struct sk_buff *skb, struct ubuf_info *ubuf,
bool zerocopy_success);
/* Unmap a pending page and release it back to the guest */ /* Unmap a pending page and release it back to the guest */
void xenvif_idx_unmap(struct xenvif_queue *queue, u16 pending_idx); void xenvif_idx_unmap(struct xenvif_queue *queue, u16 pending_idx);
......
...@@ -1091,7 +1091,7 @@ static int xenvif_handle_frag_list(struct xenvif_queue *queue, struct sk_buff *s ...@@ -1091,7 +1091,7 @@ static int xenvif_handle_frag_list(struct xenvif_queue *queue, struct sk_buff *s
uarg = skb_shinfo(skb)->destructor_arg; uarg = skb_shinfo(skb)->destructor_arg;
/* increase inflight counter to offset decrement in callback */ /* increase inflight counter to offset decrement in callback */
atomic_inc(&queue->inflight_packets); atomic_inc(&queue->inflight_packets);
uarg->callback(uarg, true); uarg->callback(NULL, uarg, true);
skb_shinfo(skb)->destructor_arg = NULL; skb_shinfo(skb)->destructor_arg = NULL;
/* Fill the skb with the new (local) frags. */ /* Fill the skb with the new (local) frags. */
...@@ -1228,7 +1228,8 @@ static int xenvif_tx_submit(struct xenvif_queue *queue) ...@@ -1228,7 +1228,8 @@ static int xenvif_tx_submit(struct xenvif_queue *queue)
return work_done; return work_done;
} }
void xenvif_zerocopy_callback(struct ubuf_info *ubuf, bool zerocopy_success) void xenvif_zerocopy_callback(struct sk_buff *skb, struct ubuf_info *ubuf,
bool zerocopy_success)
{ {
unsigned long flags; unsigned long flags;
pending_ring_idx_t index; pending_ring_idx_t index;
......
...@@ -381,7 +381,8 @@ static void vhost_zerocopy_signal_used(struct vhost_net *net, ...@@ -381,7 +381,8 @@ static void vhost_zerocopy_signal_used(struct vhost_net *net,
} }
} }
static void vhost_zerocopy_callback(struct ubuf_info *ubuf, bool success) static void vhost_zerocopy_callback(struct sk_buff *skb,
struct ubuf_info *ubuf, bool success)
{ {
struct vhost_net_ubuf_ref *ubufs = ubuf->ctx; struct vhost_net_ubuf_ref *ubufs = ubuf->ctx;
struct vhost_virtqueue *vq = ubufs->vq; struct vhost_virtqueue *vq = ubufs->vq;
......
...@@ -461,7 +461,8 @@ enum { ...@@ -461,7 +461,8 @@ enum {
* The desc field is used to track userspace buffer index. * The desc field is used to track userspace buffer index.
*/ */
struct ubuf_info { struct ubuf_info {
void (*callback)(struct ubuf_info *, bool zerocopy_success); void (*callback)(struct sk_buff *, struct ubuf_info *,
bool zerocopy_success);
union { union {
struct { struct {
unsigned long desc; unsigned long desc;
...@@ -493,7 +494,8 @@ struct ubuf_info *sock_zerocopy_realloc(struct sock *sk, size_t size, ...@@ -493,7 +494,8 @@ struct ubuf_info *sock_zerocopy_realloc(struct sock *sk, size_t size,
void sock_zerocopy_put_abort(struct ubuf_info *uarg, bool have_uref); void sock_zerocopy_put_abort(struct ubuf_info *uarg, bool have_uref);
void sock_zerocopy_callback(struct ubuf_info *uarg, bool success); void sock_zerocopy_callback(struct sk_buff *skb, struct ubuf_info *uarg,
bool success);
int skb_zerocopy_iter_dgram(struct sk_buff *skb, struct msghdr *msg, int len); int skb_zerocopy_iter_dgram(struct sk_buff *skb, struct msghdr *msg, int len);
int skb_zerocopy_iter_stream(struct sock *sk, struct sk_buff *skb, int skb_zerocopy_iter_stream(struct sock *sk, struct sk_buff *skb,
...@@ -1473,20 +1475,17 @@ static inline void *skb_zcopy_get_nouarg(struct sk_buff *skb) ...@@ -1473,20 +1475,17 @@ static inline void *skb_zcopy_get_nouarg(struct sk_buff *skb)
static inline void skb_zcopy_put(struct ubuf_info *uarg) static inline void skb_zcopy_put(struct ubuf_info *uarg)
{ {
if (uarg) if (uarg)
uarg->callback(uarg, true); uarg->callback(NULL, uarg, true);
} }
/* Release a reference on a zerocopy structure */ /* 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 zerocopy_success)
{ {
struct ubuf_info *uarg = skb_zcopy(skb); struct ubuf_info *uarg = skb_zcopy(skb);
if (uarg) { if (uarg) {
if (skb_zcopy_is_nouarg(skb)) { if (!skb_zcopy_is_nouarg(skb))
/* no notification callback */ uarg->callback(skb, uarg, zerocopy_success);
} else {
uarg->callback(uarg, zerocopy);
}
skb_shinfo(skb)->tx_flags &= ~SKBTX_ZEROCOPY_FRAG; skb_shinfo(skb)->tx_flags &= ~SKBTX_ZEROCOPY_FRAG;
} }
......
...@@ -1242,7 +1242,8 @@ static void __sock_zerocopy_callback(struct ubuf_info *uarg) ...@@ -1242,7 +1242,8 @@ static void __sock_zerocopy_callback(struct ubuf_info *uarg)
sock_put(sk); sock_put(sk);
} }
void sock_zerocopy_callback(struct ubuf_info *uarg, bool success) void sock_zerocopy_callback(struct sk_buff *skb, struct ubuf_info *uarg,
bool success)
{ {
uarg->zerocopy = uarg->zerocopy & success; uarg->zerocopy = uarg->zerocopy & success;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment