@@ -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;
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(-)