All Virtuozzo development lists (kernel + QEMU)
 help / color / mirror / Atom feed
From: Konstantin Khorenko <khorenko@virtuozzo.com>
Subject: Re: [Devel] [PATCH vz10 3/5] fixup! vhost/vsock: only refuse connection when guest has never been ready
Date: Tue, 18 Aug 2026 18:53:46 +0200	[thread overview]
Message-ID: <0f1f40cf-7f88-401f-b58f-ecc15a82ef8f@virtuozzo.com> (raw)
In-Reply-To: <20260625181637.1555685-3-eva.kurchatova@virtuozzo.com>

On 6/25/26 20:16, Eva Kurchatova wrote:
> From: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
> 
> 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.

s/beed/been/

> 
> 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@virtuozzo.com>
> ---
>  drivers/vhost/vsock.c | 31 ++++++++++++++-----------------
>  1 file changed, 14 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
> index d4c3f94308db..f652f47956d7 100644
> --- a/drivers/vhost/vsock.c
> +++ b/drivers/vhost/vsock.c
> @@ -59,6 +59,7 @@ struct vhost_vsock {
>  
>  	u32 guest_cid;
>  	bool seqpacket_allow;
> +	bool started_once;	/* latched in vhost_vsock_start(); never cleared */
>  	bool cpr_paused;	/* between stop and next start; queues sends */
>  };

static int vhost_vsock_dev_open(struct inode *inode, struct file *file)
{
...
        vsock = kvmalloc(sizeof(*vsock), GFP_KERNEL | __GFP_RETRY_MAYFAIL);

So, not zeroing struct fields here on allocation.
.started_once is not directly initialized => can have any start value.

>  
> @@ -289,24 +290,17 @@ 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.

Why you drop this part of the comment? It looks useful.

> +	/*
> +	 * 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.
>  	 */
> -	/* cpr_paused: queue across CPR; else NULL backend means not ready. */
> -	if (unlikely(!data_race(vhost_vq_get_backend(&vsock->vqs[VSOCK_VQ_RX])))) {
> -		smp_rmb();	/* pairs with smp_wmb() in start/drop_backends */
> -		if (!READ_ONCE(vsock->cpr_paused)) {

(kostja at f0)/git/vzkernel.vz10:git grep cpr_paused
drivers/vhost/vsock.c:  bool cpr_paused;        /* between stop and next start; queues sends */
drivers/vhost/vsock.c:  /* cpr_paused: queue across CPR; else NULL backend means not ready. */
drivers/vhost/vsock.c:          if (!READ_ONCE(vsock->cpr_paused)) {
drivers/vhost/vsock.c:  WRITE_ONCE(vsock->cpr_paused, false);
drivers/vhost/vsock.c:          WRITE_ONCE(vsock->cpr_paused, true);
drivers/vhost/vsock.c:  vsock->cpr_paused = false;

So you are dropping the only READ of this vsock->cpr_paused, so it's not needed anymore after this patch.

> -			rcu_read_unlock();
> -			kfree_skb(skb);
> -			return -EHOSTUNREACH;
> -		}
> +	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;
>  	}
>  
>  	if (virtio_vsock_skb_reply(skb))
> @@ -637,6 +631,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;
>  


  parent reply	other threads:[~2026-08-18 16:53 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20260625181637.1555685-1-eva.kurchatova@virtuozzo.com>
     [not found] ` <20260625181637.1555685-3-eva.kurchatova@virtuozzo.com>
2026-08-18 16:41   ` Konstantin Khorenko
2026-08-19  9:01     ` Andrey Drobyshev
2026-08-18 16:53   ` Konstantin Khorenko [this message]
     [not found] ` <20260625181637.1555685-4-eva.kurchatova@virtuozzo.com>
2026-08-18 16:56   ` [Devel] [PATCH vz10 4/5] fixup! vhost/vsock: re-scan TX virtqueue on device start Konstantin Khorenko
     [not found] ` <20260625181637.1555685-5-eva.kurchatova@virtuozzo.com>
2026-08-18 17:00   ` [Devel] [PATCH vz10 5/5] fixup! samples/bpf: fix -Wduplicate-decl-specifier and -Wmissing-declarations Konstantin Khorenko
2026-08-26 16:49     ` Konstantin Khorenko
2026-08-26 20:08     ` Eva Kurchatova (Virtuozzo)
2026-08-27 12:42       ` Konstantin Khorenko
2026-08-27 14:29         ` Eva Kurchatova (Virtuozzo)

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=0f1f40cf-7f88-401f-b58f-ecc15a82ef8f@virtuozzo.com \
    --to=khorenko@virtuozzo.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.