From: Antonio Quartulli <antonio@mandelbit.com>
To: willemdebruijn.kernel@gmail.com, jasowangio@gmail.com
Cc: Antonio Quartulli <antonio@mandelbit.com>,
andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@kernel.org,
kuba@kernel.org, pabeni@redhat.com, horms@kernel.org,
mst@redhat.com, eperezma@redhat.com, ast@kernel.org,
daniel@iogearbox.net, hawk@kernel.org, john.fastabend@gmail.com,
sdf@fomichev.me, netdev@vger.kernel.org,
virtualization@lists.linux.dev, bpf@vger.kernel.org
Subject: [PATCH net] tun: complete the zerocopy buffer of packets consumed by XDP
Date: Sat, 14 Nov 2026 00:28:41 +0100 [thread overview]
Message-ID: <20261113232843.2338734-1-antonio@mandelbit.com> (raw)
When vhost-net passes a zerocopy buffer that tun_get_user() does not use,
because the packet spans too many pages, the packet is copied and the
buffer completed. If the copy goes through build_skb() and native XDP
consumes the packet (DROP, TX or REDIRECT), tun_get_user() returns
without completing it: vhost-net never gets the descriptor back, and
closing the vhost-net device then blocks forever.
Complete it in that case too, as copied.
Reproducer: vhost-net with experimental_zcopytx=1 on a tap device with a
native XDP_DROP program; send one 806-byte packet as 40 descriptors, each
in its own page. The descriptor is never returned and close() of the
vhost-net fd does not return. With the patch it is returned.
Tested in an x86-64 VM with the reproducer and the tun kselftest.
Found by the Sashiko AI review bot, as a pre-existing issue while
reviewing an unrelated tun patch, and confirmed with the reproducer.
Link: https://sashiko.dev/#/bug/linux-f9997fb6-303f-41d6-93e2-60c392b1856f
Fixes: 761876c857cb ("tap: XDP support")
Signed-off-by: Antonio Quartulli <antonio@mandelbit.com>
---
Notes:
- Completed as copied (success false), as the copy path does: the packet
was copied into a page fragment.
- net-next replaced ubuf_info->ops with net_zcopy_complete() in
ecca9bb2c855; there the call becomes
net_zcopy_complete(NULL, msg_control, false).
drivers/net/tun.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 86fd44e10755..927196840725 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1871,8 +1871,15 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
err = PTR_ERR_OR_ZERO(skb);
if (err)
goto drop;
- if (!skb)
+ if (!skb) {
+ /* consumed by XDP, after copying */
+ if (msg_control) {
+ struct ubuf_info *uarg = msg_control;
+
+ uarg->ops->complete(NULL, uarg, false);
+ }
return total_len;
+ }
} else {
if (!zerocopy) {
copylen = len;
base-commit: ead6fa9a0ab194f02a2f36d634b193e9c5f9a1c6
--
2.56.0
reply other threads:[~2026-11-13 23:28 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261113232843.2338734-1-antonio@mandelbit.com \
--to=antonio@mandelbit.com \
--cc=andrew+netdev@lunn.ch \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=davem@davemloft.net \
--cc=edumazet@kernel.org \
--cc=eperezma@redhat.com \
--cc=hawk@kernel.org \
--cc=horms@kernel.org \
--cc=jasowangio@gmail.com \
--cc=john.fastabend@gmail.com \
--cc=kuba@kernel.org \
--cc=mst@redhat.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=sdf@fomichev.me \
--cc=virtualization@lists.linux.dev \
--cc=willemdebruijn.kernel@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox