[Devel] [PATCH vz10] vhost/vsock: Refuse the connection immediately when guest isn't ready

Polina Vishneva polina.vishneva at virtuozzo.com
Fri May 15 20:02:40 MSK 2026


On Fri, 2026-05-15 at 18:44 +0200, Konstantin Khorenko wrote:
> Please check the fields i have added to your patch and next time add them as well.
> Thank you.

Thanks! Will do.

> 
> --
> Best regards,
> 
> Konstantin Khorenko,
> Virtuozzo Linux Kernel Team
> 
> On 5/15/26 14:31, Polina Vishneva wrote:
> > 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.
> > 
> > A caller that wants to know if the guest is up yet instead of waiting
> > could theoretically tune SO_VM_SOCKETS_CONNECT_TIMEOUT, but it's tricky
> > to find the right timeout, if not impossible: there's no way to
> > distinguish "guest won't reply because it's not up yet" vs "guest is up
> > and tried to reply, but was too slow".
> > 
> > Furthermore, this delay is pointless:
> > - If the guest doesn't initialize within this timeout, connect()
> >    returns ETIMEDOUT.
> > - If the guest **does** initialize, it'll reply with RST immediately,
> >    because there won't be a listener on the port yet; connect() returns
> >    ECONNRESET.
> > 
> > That's also inconsistent with the behavior at other initialization
> > stages: if a connection is attempted when the guest driver is already
> > loaded, but nothing is listening yet, we return ECONNRESET immediately
> > without waiting.
> > 
> > Fix this by checking the RX virtqueue backend in
> > vhost_transport_send_pkt() before queuing. If it's NULL, return
> > -EHOSTUNREACH immediately.
> > 
> > Callers that used to get ETIMEDOUT will now usually get EHOSTUNREACH.
> > 
> > Signed-off-by: Denis V. Lunev <den at openvz.org>
> > Co-developed-by: Polina Vishneva <polina.vishneva at virtuozzo.com>
> > Signed-off-by: Polina Vishneva <polina.vishneva at virtuozzo.com>
> > Reviewed-by: Stefano Garzarella <sgarzare at redhat.com>
> > ---
> > That's the upstream reviewed version (that's about to get accepted).
> > 
> > Changes from the previous RFC submission:
> > - ECONNREFUSED -> EHOSTUNREACH.
> > - Use vhost_transport_do_send_pkt() instead of raw .private_data access.
> > - Removed READ_ONCE().
> > - Wrapped the condition with unlikely().
> > - Updated the comment and the commit message.
> > 
> >   drivers/vhost/vsock.c | 16 ++++++++++++++++
> >   1 file changed, 16 insertions(+)
> > 
> > diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
> > index 1d8ec6bed53e..9aaab6bb8061 100644
> > --- a/drivers/vhost/vsock.c
> > +++ b/drivers/vhost/vsock.c
> > @@ -302,6 +302,22 @@ vhost_transport_send_pkt(struct sk_buff *skb, struct net *net)
> >   		return -ENODEV;
> >   	}
> >   
> > +	/* Fast-fail if the guest hasn't enabled the RX vq yet. Queuing the packet
> > +	 * and making the caller wait is pointless: even if the guest manages to init
> > +	 * within the timeout, it'll immediately reply with RST, because there's no
> > +	 * listener on the port yet.
> > +	 *
> > +	 * vhost_vq_get_backend() without vq->mutex is acceptable here: locking
> > +	 * 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.
> > +	 */
> > +	if (unlikely(!data_race(vhost_vq_get_backend(&vsock->vqs[VSOCK_VQ_RX])))) {
> > +		rcu_read_unlock();
> > +		kfree_skb(skb);
> > +		return -EHOSTUNREACH;
> > +	}
> > +
> >   	if (virtio_vsock_skb_reply(skb))
> >   		atomic_inc(&vsock->queued_replies);
> >   
> > 
> > base-commit: 8ab992f815d6736b5c7a6f5fd7bfe7bc106bb3dc



More information about the Devel mailing list