From: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
To: linux-kernel@vger.kernel.org
Cc: kvm@vger.kernel.org, virtualization@lists.linux.dev,
netdev@vger.kernel.org, sgarzare@redhat.com, mst@redhat.com,
stefanha@redhat.com, maciej.szmigiero@oracle.com,
bchaney@akamai.com, mark.kanda@oracle.com,
ptikhomirov@virtuozzo.com, den@openvz.org,
andrey.drobyshev@virtuozzo.com
Subject: [PATCH 3/4] vhost/vsock: suppress EHOSTUNREACH fast-fail during CPR pause
Date: Fri, 12 Jun 2026 19:57:17 +0300 [thread overview]
Message-ID: <20260612165718.433546-4-andrey.drobyshev@virtuozzo.com> (raw)
In-Reply-To: <20260612165718.433546-1-andrey.drobyshev@virtuozzo.com>
From: "Denis V. Lunev" <den@openvz.org>
Earlier commit ("ms/vhost/vsock: Refuse the connection immediately when
guest isn't ready") added a fast-fail in vhost_transport_send_pkt(). It
rejects every host send with -EHOSTUNREACH until the destination calls
SET_RUNNING(1). The fast-fail condition checks whether device's backends
are dropped, and if they're, the guest is considered to be not ready.
However, there might be other reasons for backends to be nulled. In
particular, when QEMU is performing CPR (checkpoint-restore) migration,
device ownership is being RESET and SET again, which leads to backends
drop and reattach. If we end up connecting during this window, an
AF_VSOCK client gets -EHOSTUNREACH, which is wrong.
Add a cpr_paused flag set inside vhost_vsock_drop_backends() when the
backend was previously live, cleared by vhost_vsock_start(). When set,
vhost_transport_send_pkt() queues the skb instead of fast-failing; the
existing kick of send_pkt_work in vhost_vsock_start() drains it on
resume. A device that has never run keeps cpr_paused == false and the
boot-time fast-fail behaviour is preserved.
Pair the cpr_paused store with the backend store using an
smp_wmb()/smp_rmb() pair so a concurrent sender on a weakly-ordered
architecture never observes (NULL backend, !paused):
Signed-off-by: Denis V. Lunev <den@openvz.org>
---
drivers/vhost/vsock.c | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index e629886e5cf8..bcaba36becd7 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -61,6 +61,7 @@ struct vhost_vsock {
u32 guest_cid;
bool seqpacket_allow;
+ bool cpr_paused; /* between stop and next start */
};
static u32 vhost_transport_get_local_cid(void)
@@ -311,11 +312,17 @@ vhost_transport_send_pkt(struct sk_buff *skb, struct net *net)
* the mutex would be too expensive in this hot path, and we already have
* all the outcomes covered: if the backend becomes NULL right after the check,
* vhost_transport_do_send_pkt() will check it under the mutex anyway.
+ *
+ * Don't fast-fail if cpr_paused is set, keep queueing skbs instead.
+ * The kick in vhost_vsock_start() will drain them on resume.
*/
if (unlikely(!data_race(vhost_vq_get_backend(&vsock->vqs[VSOCK_VQ_RX])))) {
- rcu_read_unlock();
- kfree_skb(skb);
- return -EHOSTUNREACH;
+ smp_rmb(); /* pairs with smp_wmb() in start/drop_backends */
+ if (!READ_ONCE(vsock->cpr_paused)) {
+ rcu_read_unlock();
+ kfree_skb(skb);
+ return -EHOSTUNREACH;
+ }
}
if (virtio_vsock_skb_reply(skb))
@@ -640,6 +647,9 @@ static int vhost_vsock_start(struct vhost_vsock *vsock)
mutex_unlock(&vq->mutex);
}
+ smp_wmb(); /* pairs with smp_rmb() in send_pkt */
+ WRITE_ONCE(vsock->cpr_paused, false);
+
/* Some packets may have been queued before the device was started,
* let's kick the send worker to send them.
*/
@@ -671,6 +681,11 @@ static void vhost_vsock_drop_backends(struct vhost_vsock *vsock)
lockdep_assert_held(&vsock->dev.mutex);
+ if (vhost_vq_get_backend(&vsock->vqs[VSOCK_VQ_RX])) {
+ WRITE_ONCE(vsock->cpr_paused, true);
+ smp_wmb(); /* pairs with smp_rmb() in send_pkt */
+ }
+
for (i = 0; i < ARRAY_SIZE(vsock->vqs); i++) {
vq = &vsock->vqs[i];
@@ -728,6 +743,7 @@ static int vhost_vsock_dev_open(struct inode *inode, struct file *file)
vsock->guest_cid = 0; /* no CID assigned yet */
vsock->seqpacket_allow = false;
+ vsock->cpr_paused = false;
atomic_set(&vsock->queued_replies, 0);
--
2.47.1
next prev parent reply other threads:[~2026-06-12 16:57 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-12 16:57 [PATCH 0/4] vhost/vsock: add support for VHOST_RESET_OWNER and CPR migration Andrey Drobyshev
2026-06-12 16:57 ` [PATCH 1/4] vhost/vsock: split out vhost_vsock_drop_backends helper Andrey Drobyshev
2026-06-16 13:42 ` Stefano Garzarella
2026-06-12 16:57 ` [PATCH 2/4] vhost/vsock: add VHOST_RESET_OWNER ioctl Andrey Drobyshev
2026-06-16 13:48 ` Stefano Garzarella
2026-06-16 14:10 ` Andrey Drobyshev
2026-06-16 14:26 ` Stefano Garzarella
2026-06-12 16:57 ` Andrey Drobyshev [this message]
2026-06-16 14:18 ` [PATCH 3/4] vhost/vsock: suppress EHOSTUNREACH fast-fail during CPR pause Stefano Garzarella
2026-06-16 15:58 ` Andrey Drobyshev
2026-06-16 16:13 ` Stefano Garzarella
2026-06-12 16:57 ` [PATCH 4/4] vhost/vsock: re-scan TX virtqueue on device start Andrey Drobyshev
2026-06-16 14:23 ` Stefano Garzarella
2026-06-16 15:58 ` Andrey Drobyshev
2026-06-16 13:35 ` [PATCH 0/4] vhost/vsock: add support for VHOST_RESET_OWNER and CPR migration Stefano Garzarella
2026-06-16 14:01 ` Andrey Drobyshev
2026-06-16 14:28 ` Stefano Garzarella
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=20260612165718.433546-4-andrey.drobyshev@virtuozzo.com \
--to=andrey.drobyshev@virtuozzo.com \
--cc=bchaney@akamai.com \
--cc=den@openvz.org \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=maciej.szmigiero@oracle.com \
--cc=mark.kanda@oracle.com \
--cc=mst@redhat.com \
--cc=netdev@vger.kernel.org \
--cc=ptikhomirov@virtuozzo.com \
--cc=sgarzare@redhat.com \
--cc=stefanha@redhat.com \
--cc=virtualization@lists.linux.dev \
/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
all inboxes | Powered by JetHome®