[Devel] [PATCH RFC] vhost/vsock: Refuse the connection immediately when guest isn't ready
Polina Vishneva
polina.vishneva at virtuozzo.com
Thu May 7 23:13:54 MSK 2026
From: "Denis V. Lunev" <den at openvz.org>
When the host initiates an AF_VSOCK connect() to a guest that has not
yet loaded the virtio-vsock transport (i.e. still booting), the caller
blocks for VSOCK_DEFAULT_CONNECT_TIMEOUT (2 seconds), because
vhost_transport_do_send_pkt() silently exits when
vhost_vq_get_backend(vq) returns NULL.
If the guest doesn't start listening within this timeout, connect()
returns ETIMEDOUT.
This delay is usually pointless and it doesn't well align with our
behavior at other initialization stages: for example, if a connection is
attempted when the guest driver is already loaded, but when nothing is
listening yet, it returns ECONNRESET immediately without any wait.
Fix this by checking the RX virtqueue backend in
vhost_transport_send_pkt() before queuing. If the backend is NULL,
return -ECONNREFUSED immediately.
Signed-off-by: Denis V. Lunev <den at openvz.org>
Co-authored-by: Polina Vishneva <polina.vishneva at virtuozzo.com>
Signed-off-by: Polina Vishneva <polina.vishneva at virtuozzo.com>
---
drivers/vhost/vsock.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index 1d8ec6bed53e..e6de1e23121b 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -302,6 +302,20 @@ vhost_transport_send_pkt(struct sk_buff *skb, struct net *net)
return -ENODEV;
}
+ /* If the guest has not yet initialized the RX virtqueue, fail
+ * immediately rather than queueing the packet and letting the
+ * caller wait for VSOCK_DEFAULT_CONNECT_TIMEOUT.
+ *
+ * Reading private_data without vq->mutex is a deliberate racy
+ * check: if the backend is NULL the guest driver is definitely
+ * not ready; if it becomes NULL right after, the worker
+ * (do_send_pkt) rechecks under the mutex. */
+ if (!READ_ONCE(vsock->vqs[VSOCK_VQ_RX].private_data)) {
+ rcu_read_unlock();
+ kfree_skb(skb);
+ return -ECONNREFUSED;
+ }
+
if (virtio_vsock_skb_reply(skb))
atomic_inc(&vsock->queued_replies);
@@ -624,9 +638,6 @@ static int vhost_vsock_start(struct vhost_vsock *vsock)
mutex_unlock(&vq->mutex);
}
- /* Some packets may have been queued before the device was started,
- * let's kick the send worker to send them.
- */
vhost_vq_work_queue(&vsock->vqs[VSOCK_VQ_RX], &vsock->send_pkt_work);
mutex_unlock(&vsock->dev.mutex);
--
2.53.0
More information about the Devel
mailing list