[RFC,v1,1/2] virtio/vsock: send credit update depending on SO_RCVLOWAT

Message ID f304eabe-d2ef-11b1-f115-6967632f0339@sberdevices.ru
State New
Headers
Series virtio/vsock: fix mutual rx/tx hungup |

Commit Message

Arseniy Krasnov Dec. 17, 2022, 7:45 p.m. UTC
  This adds extra condition to send credit update message during data
read to userspace. Problem arises, when sender waits for the free space
on the receiver while receiver waits in 'poll()' until 'rx_bytes' reaches
SO_RCVLOWAT value of the socket. With this patch, receiver sends credit
update message when number of bytes in it's rx queue is too small to
avoid sleeping in 'poll()'.

Signed-off-by: Arseniy Krasnov <AVKrasnov@sberdevices.ru>
---
 net/vmw_vsock/virtio_transport_common.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

-- 
2.25.1
  

Patch

diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
index a1581c77cf84..4cf26cf8a754 100644
--- a/net/vmw_vsock/virtio_transport_common.c
+++ b/net/vmw_vsock/virtio_transport_common.c
@@ -362,6 +362,7 @@  virtio_transport_stream_do_dequeue(struct vsock_sock *vsk,
 	struct virtio_vsock_sock *vvs = vsk->trans;
 	size_t bytes, total = 0;
 	struct sk_buff *skb;
+	bool low_rx_bytes;
 	int err = -EFAULT;
 	u32 free_space;
 
@@ -396,6 +397,8 @@  virtio_transport_stream_do_dequeue(struct vsock_sock *vsk,
 	}
 
 	free_space = vvs->buf_alloc - (vvs->fwd_cnt - vvs->last_fwd_cnt);
+	low_rx_bytes = (vvs->rx_bytes <
+			sock_rcvlowat(sk_vsock(vsk), 0, INT_MAX));
 
 	spin_unlock_bh(&vvs->rx_lock);
 
@@ -405,9 +408,11 @@  virtio_transport_stream_do_dequeue(struct vsock_sock *vsk,
 	 * too high causes extra messages. Too low causes transmitter
 	 * stalls. As stalls are in theory more expensive than extra
 	 * messages, we set the limit to a high value. TODO: experiment
-	 * with different values.
+	 * with different values. Also send credit update message when
+	 * number of bytes in rx queue is not enough to wake up reader.
 	 */
-	if (free_space < VIRTIO_VSOCK_MAX_PKT_BUF_SIZE)
+	if (free_space < VIRTIO_VSOCK_MAX_PKT_BUF_SIZE ||
+	    low_rx_bytes)
 		virtio_transport_send_credit_update(vsk);
 
 	return total;