Re: [PATCH v3 1/2] vsock/virtio: read virtqueues under worker locks

Bobby Eshleman <[email protected]> Thu, 30 Jul 2026 14:46:59 -0700
Newsgroups dev.linux.lists.virtualization,org.kernel.vger.kvm,org.kernel.vger.linux-kernel,org.kernel.vger.netdev
Message-ID <[email protected]>
On Wed, Jul 29, 2026 at 12:16:54PM -0700, Weiming Shi wrote:
> Commit bd50c5dc182b ("vsock/virtio: add support for device
> suspend/resume") made the *_run flags transition from false to true when
> restore installs replacement virtqueues.  The RX, TX and event workers
> read their virtqueue before locking and checking the corresponding flag,
> so a worker delayed across freeze and restore can observe the replacement
> queue's running state while retaining a pointer to the deleted queue.
> 
> Read each virtqueue under its mutex after checking the run flag, keeping
> the pointer and state in the same queue generation.
> 
> Fixes: bd50c5dc182b ("vsock/virtio: add support for device suspend/resume")
> Cc: [email protected]
> Reported-by: Xiang Mei <[email protected]>
> Link: https://lore.kernel.org/r/[email protected]
> Assisted-by: OpenAI-Codex:gpt-5
> Signed-off-by: Weiming Shi <[email protected]>
> ---
>  net/vmw_vsock/virtio_transport.c | 11 ++++++-----
>  1 file changed, 6 insertions(+), 5 deletions(-)
> 
> diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c
> index 57f2d6ec3ffc..a8e1dd95ba8c 100644
> --- a/net/vmw_vsock/virtio_transport.c
> +++ b/net/vmw_vsock/virtio_transport.c
> @@ -346,12 +346,13 @@ static void virtio_transport_tx_work(struct work_struct *work)
>  	struct virtqueue *vq;
>  	bool added = false;
>  
> -	vq = vsock->vqs[VSOCK_VQ_TX];
>  	mutex_lock(&vsock->tx_lock);
>  
>  	if (!vsock->tx_run)
>  		goto out;
>  
> +	vq = vsock->vqs[VSOCK_VQ_TX];
> +
>  	do {
>  		struct sk_buff *skb;
>  		unsigned int len;
> @@ -451,13 +452,13 @@ static void virtio_transport_event_work(struct work_struct *work)
>  		container_of(work, struct virtio_vsock, event_work);
>  	struct virtqueue *vq;
>  
> -	vq = vsock->vqs[VSOCK_VQ_EVENT];
> -
>  	mutex_lock(&vsock->event_lock);
>  
>  	if (!vsock->event_run)
>  		goto out;
>  
> +	vq = vsock->vqs[VSOCK_VQ_EVENT];
> +
>  	do {
>  		struct virtio_vsock_event *event;
>  		unsigned int len;
> @@ -634,13 +635,13 @@ static void virtio_transport_rx_work(struct work_struct *work)
>  		container_of(work, struct virtio_vsock, rx_work);
>  	struct virtqueue *vq;
>  
> -	vq = vsock->vqs[VSOCK_VQ_RX];
> -
>  	mutex_lock(&vsock->rx_lock);
>  
>  	if (!vsock->rx_run)
>  		goto out;
>  
> +	vq = vsock->vqs[VSOCK_VQ_RX];
> +
>  	do {
>  		virtqueue_disable_cb(vq);
>  		for (;;) {
> -- 
> 2.55.0
> 

Reviewed-by: Bobby Eshleman <[email protected]>