Frédéric Dalleau
2022-Aug-24 07:42 UTC
[PATCH 0/1] Stalled communication on Hyper V Sockets
Hi, After upgrading our VMs kernel, our golang software stack started facing some communication stalling on HyperV platforms. After receiving a few hundered MBs data from a vsocket in the guest, the data flows suddenly stops, and the receiver is not notified. The sender on the host times out. Since the use case is very simple, we were surprised that it was not reported, so we took time to investigate. The issue was bisected to patch below [b3f7fd54881bcba5dc529935f38] af_vsock: separate wait data loop>From there ftrace allowed to spot the problem, more details are in thepatch description. In the end, note that the patch is not HyperV specific. So maybe the reproduction rate is lower on other platforms. Let me know what you think, Fr?d?ric Dalleau Fr?d?ric Dalleau (1): vsock: Fix stalled communication on vhost sockets net/vmw_vsock/af_vsock.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) -- 2.34.1
Frédéric Dalleau
2022-Aug-24 07:42 UTC
[PATCH 1/1] vsock: Fix stalled communication on vhost sockets
After kernel upgrade, we faced some stalled communication on HyperV VMs with our golang clients. We bisected the issue to patch [b3f7fd54881bcba5dc529935f38] af_vsock: separate wait data loop When this occurred the following sequence appeared in ftrace: hvs_stream_has_data <- vsock_connectible_wait_data hvs_channel_cb <- vmbus_on_event hvs_notify_recv_pre_block <- vsock_connectible_wait_data It turned out that it was possible to enter hvs_notify_recv_pre_block with data pending in the stream. This is because the data condition must be checked between prepare_to_wait and schedule, if not the receiver may not be woken up if an event occurs after checking the condition and before prepare_to_wait. This patch moves prepare_to_wait call before the condition and at the end of loop, similar to what is done elsewhere in the same file. Signed-off-by: Fr?d?ric Dalleau <frederic.dalleau at docker.com> --- net/vmw_vsock/af_vsock.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index ee418701cdee..cd5e0dbcabe0 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -1904,9 +1904,9 @@ static int vsock_connectible_wait_data(struct sock *sk, vsk = vsock_sk(sk); err = 0; transport = vsk->transport; + prepare_to_wait(sk_sleep(sk), wait, TASK_INTERRUPTIBLE); while ((data = vsock_connectible_has_data(vsk)) == 0) { - prepare_to_wait(sk_sleep(sk), wait, TASK_INTERRUPTIBLE); if (sk->sk_err != 0 || (sk->sk_shutdown & RCV_SHUTDOWN) || @@ -1937,6 +1937,7 @@ static int vsock_connectible_wait_data(struct sock *sk, err = -EAGAIN; break; } + prepare_to_wait(sk_sleep(sk), wait, TASK_INTERRUPTIBLE); } finish_wait(sk_sleep(sk), wait); -- 2.34.1