[Devel] [PATCH VZ10] vhost/vsock: only refuse connection when guest has never been ready

Konstantin Khorenko khorenko at virtuozzo.com
Tue Jul 7 14:55:54 MSK 2026


ping here.

--
Best regards,

Konstantin Khorenko,
Virtuozzo Linux Kernel Team

On 5/21/26 23:36, Denis V. Lunev wrote:
> On 5/21/26 23:31, Andrey Drobyshev wrote:
>> This email originated from an IP that might not be authorized by the domain it was sent from.
>> Do not click links or open attachments unless it is an email you expected to receive.
>> Commit 4ff28534c799 ("ms/vhost/vsock: Refuse the connection immediately
>> when guest isn't ready") added a check which immediately returns
>> EHOSTUNREACH when the guest isn't ready yet.  Namely, we check that guest
>> hasn't enabled the RX vq yet, i.e. virtio-vsock has never beed enabled.
>>
>> However, the check also affects the transient state when backend is
>> temporarily set to NULL during VHOST_VSOCK_SET_RUNNING(0).  Notably,
>> this is the case with qemu-update operation, during which we perform
>> VHOST_RESET_OWNER.  In this case sendmsg()/connect() on otherwise healthy
>> connection gets EHOSTUNREACH.
>>
>> Gate the fast-fail on a sticky started_once bit set in
>> vhost_vsock_start() and never cleared.  Once the guest has brought
>> up virtio-vsock at least once, a NULL backend means a transient stop
>> window and the packet must be queued for vhost_vsock_start() to drain
>> on re-attach.
>>
>> Fixes: 4ff28534c799 ("ms/vhost/vsock: Refuse the connection immediately when guest isn't ready")
>> https://virtuozzo.atlassian.net/browse/VSTOR-131956
>> Signed-off-by: Andrey Drobyshev <andrey.drobyshev at virtuozzo.com>
>> ---
>>  drivers/vhost/vsock.c | 21 +++++++++++----------
>>  1 file changed, 11 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
>> index 0a518c3d1596..f39354db630e 100644
>> --- a/drivers/vhost/vsock.c
>> +++ b/drivers/vhost/vsock.c
>> @@ -57,6 +57,7 @@ struct vhost_vsock {
>>  
>>  	u32 guest_cid;
>>  	bool seqpacket_allow;
>> +	bool started_once;	/* latched in vhost_vsock_start(); never cleared */
>>  };
>>  
>>  static u32 vhost_transport_get_local_cid(void)
>> @@ -285,17 +286,14 @@ vhost_transport_send_pkt(struct sk_buff *skb)
>>  		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.
>> +	/*
>> +	 * Fast-fail only when the guest has never enabled virtio-vsock.
>> +	 * Once it has, a NULL backend means a transient SET_RUNNING(0)
>> +	 * window (e.g. VHOST_RESET_OWNER); the packet must be
>> +	 * queued for vhost_vsock_start() to drain on re-attach.
>>  	 */
>> -	if (unlikely(!data_race(vhost_vq_get_backend(&vsock->vqs[VSOCK_VQ_RX])))) {
>> +	if (unlikely(!READ_ONCE(vsock->started_once)) &&
>> +	    !data_race(vhost_vq_get_backend(&vsock->vqs[VSOCK_VQ_RX]))) {
>>  		rcu_read_unlock();
>>  		kfree_skb(skb);
>>  		return -EHOSTUNREACH;
>> @@ -615,6 +613,9 @@ static int vhost_vsock_start(struct vhost_vsock *vsock)
>>  	 */
>>  	vhost_vq_work_queue(&vsock->vqs[VSOCK_VQ_RX], &vsock->send_pkt_work);
>>  
>> +	/* See vhost_transport_send_pkt(); never cleared. */
>> +	WRITE_ONCE(vsock->started_once, true);
>> +
>>  	mutex_unlock(&vsock->dev.mutex);
>>  	return 0;
>>  
> what about guest reset + stuck in BIOS?
> 
> Den
> _______________________________________________
> Devel mailing list
> Devel at openvz.org
> https://lists.openvz.org/mailman/listinfo/devel



More information about the Devel mailing list