Ning Bo reported an abnormal 2-second gap when booting Kata container [1]. The unconditional timeout is caused by VSOCK_DEFAULT_CONNECT_TIMEOUT of connect at client side. The vhost vsock client tries to connect an initlizing virtio vsock server. The abnormal flow looks like: host-userspace vhost vsock guest vsock ============== =========== ============ connect() --------> vhost_transport_send_pkt_work() initializing | vq->private_data==NULL | will not be queued V schedule_timeout(2s) vhost_vsock_start() <--------- device ready set vq->private_data wait for 2s and failed connect() again vq->private_data!=NULL recv connecting pkt 1. host userspace sends a connect pkt, at that time, guest vsock is under initializing, hence the vhost_vsock_start has not been called. So vq->private_data==NULL, and the pkt is not been queued to send to guest. 2. then it sleeps for 2s 3. after guest vsock finishes initializing, vq->private_data is set. 4. When host userspace wakes up after 2s, send connecting pkt again, everything is fine. This fixes it by checking vq->private_data in vhost_transport_send_pkt, and return at once if !vq->private_data. This makes user connect() be returned with ECONNREFUSED. After this patch, kata-runtime (with vsock enabled) boottime reduces from 3s to 1s on ThunderX2 arm64 server. [1] https://github.com/kata-containers/runtime/issues/1917 Reported-by: Ning Bo <n.b@xxxxxxxx> Signed-off-by: Jia He <justin.he@xxxxxxx> --- drivers/vhost/vsock.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c index e36aaf9ba7bd..67474334dd88 100644 --- a/drivers/vhost/vsock.c +++ b/drivers/vhost/vsock.c @@ -241,6 +241,7 @@ vhost_transport_send_pkt(struct virtio_vsock_pkt *pkt) { struct vhost_vsock *vsock; int len = pkt->len; + struct vhost_virtqueue *vq; rcu_read_lock(); @@ -252,6 +253,13 @@ vhost_transport_send_pkt(struct virtio_vsock_pkt *pkt) return -ENODEV; } + vq = &vsock->vqs[VSOCK_VQ_RX]; + if (!vq->private_data) { + rcu_read_unlock(); + virtio_transport_free_pkt(pkt); + return -ECONNREFUSED; + } + if (pkt->reply) atomic_inc(&vsock->queued_replies); -- 2.17.1