[PATCH net-next v7 5/9] tun/tap: add unconsume function for returning entries to ptr_ring
From: Simon Schippers <hidden>
Date: 2026-01-07 21:06:15
Also in:
kvm, lkml, virtualization
Subsystem:
networking drivers, the rest, tun/tap driver · Maintainers:
Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds, Willem de Bruijn, Jason Wang
Add {tun,tap}_ring_unconsume() wrappers to allow external modules
(e.g. vhost-net) to return previously consumed entries back to the
ptr_ring. The functions delegate to ptr_ring_unconsume() and take a
destroy callback for entries that cannot be returned to the ring.
Co-developed-by: Tim Gebauer <redacted>
Signed-off-by: Tim Gebauer <redacted>
Co-developed by: Jon Kohler [off-list ref]
Signed-off-by: Jon Kohler <redacted>
Signed-off-by: Simon Schippers <redacted>
---
drivers/net/tap.c | 10 ++++++++++
drivers/net/tun.c | 10 ++++++++++
include/linux/if_tap.h | 4 ++++
include/linux/if_tun.h | 5 +++++
4 files changed, 29 insertions(+)
diff --git a/drivers/net/tap.c b/drivers/net/tap.c
index 7e3b4eed797c..4ffe4e95b5a6 100644
--- a/drivers/net/tap.c
+++ b/drivers/net/tap.c@@ -797,6 +797,16 @@ int tap_ring_consume_batched(struct file *file, void **array, int n) } EXPORT_SYMBOL_GPL(tap_ring_consume_batched); +void tap_ring_unconsume(struct file *file, void **batch, int n, + void (*destroy)(void *)) +{ + struct tap_queue *q = file->private_data; + struct ptr_ring *ring = &q->ring; + + ptr_ring_unconsume(ring, batch, n, destroy); +} +EXPORT_SYMBOL_GPL(tap_ring_unconsume); + static ssize_t tap_do_read(struct tap_queue *q, struct iov_iter *to, int noblock, struct sk_buff *skb)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index db3b72025cfb..d44d206c65e8 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c@@ -3759,6 +3759,16 @@ int tun_ring_consume_batched(struct file *file, void **array, int n) } EXPORT_SYMBOL_GPL(tun_ring_consume_batched); +void tun_ring_unconsume(struct file *file, void **batch, int n, + void (*destroy)(void *)) +{ + struct tun_file *tfile = file->private_data; + struct ptr_ring *ring = &tfile->tx_ring; + + ptr_ring_unconsume(ring, batch, n, destroy); +} +EXPORT_SYMBOL_GPL(tun_ring_unconsume); + struct ptr_ring *tun_get_tx_ring(struct file *file) { struct tun_file *tfile;
diff --git a/include/linux/if_tap.h b/include/linux/if_tap.h
index cf8b90320b8d..28326a69745a 100644
--- a/include/linux/if_tap.h
+++ b/include/linux/if_tap.h@@ -12,6 +12,8 @@ struct socket; struct socket *tap_get_socket(struct file *); struct ptr_ring *tap_get_ptr_ring(struct file *file); int tap_ring_consume_batched(struct file *file, void **array, int n); +void tap_ring_unconsume(struct file *file, void **batch, int n, + void (*destroy)(void *)); #else #include <linux/err.h> #include <linux/errno.h>
@@ -28,6 +30,8 @@ static inline int tap_ring_consume_batched(struct file *f, { return 0; } +static inline void tap_ring_unconsume(struct file *file, void **batch, + int n, void (*destroy)(void *)) {} #endif /* CONFIG_TAP */ /*
diff --git a/include/linux/if_tun.h b/include/linux/if_tun.h
index 444dda75a372..1274c6b34eb6 100644
--- a/include/linux/if_tun.h
+++ b/include/linux/if_tun.h@@ -23,6 +23,8 @@ struct tun_msg_ctl { struct socket *tun_get_socket(struct file *); struct ptr_ring *tun_get_tx_ring(struct file *file); int tun_ring_consume_batched(struct file *file, void **array, int n); +void tun_ring_unconsume(struct file *file, void **batch, int n, + void (*destroy)(void *)); static inline bool tun_is_xdp_frame(void *ptr) {
@@ -62,6 +64,9 @@ static inline int tun_ring_consume_batched(struct file *file, return 0; } +static inline void tun_ring_unconsume(struct file *file, void **batch, + int n, void (*destroy)(void *)) {} + static inline bool tun_is_xdp_frame(void *ptr) { return false;
--
2.43.0