[Devel] [PATCH hci-8.0 1/1] vsock/virtio: fix `rx_bytes` accounting for stream sockets

Konstantin Khorenko khorenko at virtuozzo.com
Thu May 28 14:47:20 MSK 2026


The patch does not apply.

--
Best regards,

Konstantin Khorenko,
Virtuozzo Linux Kernel Team

On 5/25/26 16:06, Denis V. Lunev wrote:
> From: Stefano Garzarella <sgarzare at redhat.com>
> 
> In `struct virtio_vsock_sock`, we maintain two counters:
> - `rx_bytes`: used internally to track how many bytes have been read.
>   This supports mechanisms like .stream_has_data() and sock_rcvlowat().
> - `fwd_cnt`: used for the credit mechanism to inform available receive
>   buffer space to the remote peer.
> 
> These counters are updated via virtio_transport_inc_rx_pkt() and
> virtio_transport_dec_rx_pkt().
> 
> Since the beginning with commit 06a8fc78367d ("VSOCK: Introduce
> virtio_vsock_common.ko"), we call virtio_transport_dec_rx_pkt() in
> virtio_transport_stream_do_dequeue() only when we consume the entire
> packet, so partial reads, do not update `rx_bytes` and `fwd_cnt`.
> 
> This is fine for `fwd_cnt`, because we still have space used for the
> entire packet, and we don't want to update the credit for the other
> peer until we free the space of the entire packet. However, this
> causes `rx_bytes` to be stale on partial reads.
> 
> Previously, this didn’t cause issues because `rx_bytes` was used only by
> .stream_has_data(), and any unread portion of a packet implied data was
> still available. However, since commit 93b808876682
> ("virtio/vsock: fix logic which reduces credit update messages"), we now
> rely on `rx_bytes` to determine if a credit update should be sent when
> the data in the RX queue drops below SO_RCVLOWAT value.
> 
> This patch fixes the accounting by updating `rx_bytes` with the number
> of bytes actually read, even on partial reads, while leaving `fwd_cnt`
> untouched until the packet is fully consumed. Also introduce a new
> `buf_used` counter to check that the remote peer is honoring the given
> credit; this was previously done via `rx_bytes`.
> 
> Fixes: 93b808876682 ("virtio/vsock: fix logic which reduces credit update messages")
> Signed-off-by: Stefano Garzarella <sgarzare at redhat.com>
> Link: https://patch.msgid.link/20250521121705.196379-1-sgarzare@redhat.com
> Signed-off-by: Paolo Abeni <pabeni at redhat.com>
> https://virtuozzo.atlassian.net/browse/VSTOR-132908
> Signed-off-by: Denis V. Lunev <den at openvz.org>
> ---
>  include/linux/virtio_vsock.h            |  1 +
>  net/vmw_vsock/virtio_transport_common.c | 26 +++++++++++++++----------
>  2 files changed, 17 insertions(+), 10 deletions(-)
> 
> diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h
> index 0387d64e2c66..36fb3edfa403 100644
> --- a/include/linux/virtio_vsock.h
> +++ b/include/linux/virtio_vsock.h
> @@ -140,6 +140,7 @@ struct virtio_vsock_sock {
>  	u32 last_fwd_cnt;
>  	u32 rx_bytes;
>  	u32 buf_alloc;
> +	u32 buf_used;
>  	struct sk_buff_head rx_queue;
>  	u32 msg_count;
>  };
> diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
> index 51a494b69be8..ff295a781822 100644
> --- a/net/vmw_vsock/virtio_transport_common.c
> +++ b/net/vmw_vsock/virtio_transport_common.c
> @@ -438,18 +438,20 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk,
>  static bool virtio_transport_inc_rx_pkt(struct virtio_vsock_sock *vvs,
>  					u32 len)
>  {
> -	if (vvs->rx_bytes + len > vvs->buf_alloc)
> +	if (vvs->buf_used + len > vvs->buf_alloc)
>  		return false;
>  
>  	vvs->rx_bytes += len;
> +	vvs->buf_used += len;
>  	return true;
>  }
>  
>  static void virtio_transport_dec_rx_pkt(struct virtio_vsock_sock *vvs,
> -					u32 len)
> +					u32 bytes_read, u32 bytes_dequeued)
>  {
> -	vvs->rx_bytes -= len;
> -	vvs->fwd_cnt += len;
> +	vvs->rx_bytes -= bytes_read;
> +	vvs->buf_used -= bytes_dequeued;
> +	vvs->fwd_cnt += bytes_dequeued;
>  }
>  
>  void virtio_transport_inc_tx_pkt(struct virtio_vsock_sock *vvs, struct sk_buff *skb)
> @@ -578,11 +580,11 @@ virtio_transport_stream_do_dequeue(struct vsock_sock *vsk,
>  				   size_t len)
>  {
>  	struct virtio_vsock_sock *vvs = vsk->trans;
> -	size_t bytes, total = 0;
>  	struct sk_buff *skb;
>  	u32 fwd_cnt_delta;
>  	bool low_rx_bytes;
>  	int err = -EFAULT;
> +	size_t total = 0;
>  	u32 free_space;
>  
>  	spin_lock_bh(&vvs->rx_lock);
> @@ -594,6 +596,8 @@ virtio_transport_stream_do_dequeue(struct vsock_sock *vsk,
>  	}
>  
>  	while (total < len && !skb_queue_empty(&vvs->rx_queue)) {
> +		size_t bytes, dequeued = 0;
> +
>  		skb = skb_peek(&vvs->rx_queue);
>  
>  		bytes = min_t(size_t, len - total,
> @@ -617,12 +621,12 @@ virtio_transport_stream_do_dequeue(struct vsock_sock *vsk,
>  		VIRTIO_VSOCK_SKB_CB(skb)->offset += bytes;
>  
>  		if (skb->len == VIRTIO_VSOCK_SKB_CB(skb)->offset) {
> -			u32 pkt_len = le32_to_cpu(virtio_vsock_hdr(skb)->len);
> -
> -			virtio_transport_dec_rx_pkt(vvs, pkt_len);
> +			dequeued = le32_to_cpu(virtio_vsock_hdr(skb)->len);
>  			__skb_unlink(skb, &vvs->rx_queue);
>  			consume_skb(skb);
>  		}
> +
> +		virtio_transport_dec_rx_pkt(vvs, bytes, dequeued);
>  	}
>  
>  	fwd_cnt_delta = vvs->fwd_cnt - vvs->last_fwd_cnt;
> @@ -778,7 +782,7 @@ static int virtio_transport_seqpacket_do_dequeue(struct vsock_sock *vsk,
>  				msg->msg_flags |= MSG_EOR;
>  		}
>  
> -		virtio_transport_dec_rx_pkt(vvs, pkt_len);
> +		virtio_transport_dec_rx_pkt(vvs, pkt_len, pkt_len);
>  		kfree_skb(skb);
>  	}
>  
> @@ -1722,6 +1726,7 @@ int virtio_transport_read_skb(struct vsock_sock *vsk, skb_read_actor_t recv_acto
>  	struct sock *sk = sk_vsock(vsk);
>  	struct virtio_vsock_hdr *hdr;
>  	struct sk_buff *skb;
> +	u32 pkt_len;
>  	int off = 0;
>  	int err;
>  
> @@ -1739,7 +1744,8 @@ int virtio_transport_read_skb(struct vsock_sock *vsk, skb_read_actor_t recv_acto
>  	if (le32_to_cpu(hdr->flags) & VIRTIO_VSOCK_SEQ_EOM)
>  		vvs->msg_count--;
>  
> -	virtio_transport_dec_rx_pkt(vvs, le32_to_cpu(hdr->len));
> +	pkt_len = le32_to_cpu(hdr->len);
> +	virtio_transport_dec_rx_pkt(vvs, pkt_len, pkt_len);
>  	spin_unlock_bh(&vvs->rx_lock);
>  
>  	virtio_transport_send_credit_update(vsk);



More information about the Devel mailing list