From nobody Wed Nov 5 13:15:32 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=yandex-team.ru Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1534437475393259.2544221664515; Thu, 16 Aug 2018 09:37:55 -0700 (PDT) Received: from localhost ([::1]:56904 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fqLHR-00081v-4K for importer@patchew.org; Thu, 16 Aug 2018 12:37:49 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38027) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fqKGi-00047l-HV for qemu-devel@nongnu.org; Thu, 16 Aug 2018 11:33:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fqKGh-0002p0-91 for qemu-devel@nongnu.org; Thu, 16 Aug 2018 11:33:00 -0400 Received: from forwardcorp1j.cmail.yandex.net ([2a02:6b8:0:1630::190]:52985) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fqKGg-0002o6-Rn for qemu-devel@nongnu.org; Thu, 16 Aug 2018 11:32:59 -0400 Received: from mxbackcorp1j.mail.yandex.net (mxbackcorp1j.mail.yandex.net [IPv6:2a02:6b8:0:1619::162]) by forwardcorp1j.cmail.yandex.net (Yandex) with ESMTP id A51F420EDD; Thu, 16 Aug 2018 18:32:57 +0300 (MSK) Received: from smtpcorp1p.mail.yandex.net (smtpcorp1p.mail.yandex.net [2a02:6b8:0:1472:2741:0:8b6:10]) by mxbackcorp1j.mail.yandex.net (nwsmtp/Yandex) with ESMTP id 7xA44owgpU-WvPGrnTG; Thu, 16 Aug 2018 18:32:57 +0300 Received: from dynamic-red.dhcp.yndx.net (dynamic-red.dhcp.yndx.net [2a02:6b8:0:40c:e1bb:a1a7:a235:d6b4]) by smtpcorp1p.mail.yandex.net (nwsmtp/Yandex) with ESMTPSA id 7WDIxKFPmc-WvXWSJn9; Thu, 16 Aug 2018 18:32:57 +0300 (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (Client certificate not present) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex-team.ru; s=default; t=1534433577; bh=oIvlhwZ4cJixSu1+9vchNOK9IiaDq6qh2TCuGX35Cus=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=nWDB2EuY0itpf9cFabbg2m3/eQMZgi/rJXhLvZmtn3YgU1KBE3z75dTbe9P7iZEXY 1zwz8xR03UrSQd+Gdj9OgfDynpAfI1Ugtue6Md8vJmzOCYcdPxSNmWU/NkQpd2eUbf F06pgUi22a12i9DcWVpwt90lbtfbvzvPTK2DWzE4= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex-team.ru; s=default; t=1534433577; bh=oIvlhwZ4cJixSu1+9vchNOK9IiaDq6qh2TCuGX35Cus=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=nWDB2EuY0itpf9cFabbg2m3/eQMZgi/rJXhLvZmtn3YgU1KBE3z75dTbe9P7iZEXY 1zwz8xR03UrSQd+Gdj9OgfDynpAfI1Ugtue6Md8vJmzOCYcdPxSNmWU/NkQpd2eUbf F06pgUi22a12i9DcWVpwt90lbtfbvzvPTK2DWzE4= Authentication-Results: smtpcorp1p.mail.yandex.net; dkim=pass header.i=@yandex-team.ru From: Yury Kotov To: qemu-devel@nongnu.org Date: Thu, 16 Aug 2018 18:32:43 +0300 Message-Id: <1534433563-30865-4-git-send-email-yury-kotov@yandex-team.ru> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1534433563-30865-1-git-send-email-yury-kotov@yandex-team.ru> References: <1534433563-30865-1-git-send-email-yury-kotov@yandex-team.ru> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a02:6b8:0:1630::190 Subject: [Qemu-devel] [PATCH 3/3] vhost-user: add reconnect support for vhost-user X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , Paolo Bonzini , Evgeny Yakovlev , "Michael S. Tsirkin" Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDMRC_1 RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Now, vhost device will stop if backend had restarted. Even if we specify 'reconnect' parameter for chardev and connection will be restored, vhost device will not be resumed. To resume device we should sync with backend again after reconnect. Add vhost_dev_reconnect extern function to vhost and add reconnect handler to vhost-user which uses vhost_dev_reconnect to retry handshake with vhost-user backend. Signed-off-by: Yury Kotov Signed-off-by: Evgeny Yakovlev --- hw/virtio/vhost-user.c | 65 +++++++++++++++++++++++++++++++++++++++++++= ---- hw/virtio/vhost.c | 31 ++++++++++++++++++++++ include/hw/virtio/vhost.h | 1 + 3 files changed, 92 insertions(+), 5 deletions(-) diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c index b041343..5c7e113 100644 --- a/hw/virtio/vhost-user.c +++ b/hw/virtio/vhost-user.c @@ -1121,6 +1121,17 @@ out: return ret; } =20 +static void vhost_close_slave_channel(struct vhost_dev *dev) +{ + struct vhost_user *u =3D dev->opaque; + + if (u->slave_fd >=3D 0) { + qemu_set_fd_handler(u->slave_fd, NULL, NULL, NULL); + close(u->slave_fd); + u->slave_fd =3D -1; + } +} + /* * Called back from the postcopy fault thread when a fault is received on = our * ufd. @@ -1334,6 +1345,41 @@ static int vhost_user_postcopy_notifier(NotifierWith= Return *notifier, return 0; } =20 +static void vhost_user_reconnect_handler(void *opaque, int event) +{ + struct vhost_user *u =3D opaque; + struct vhost_dev *dev =3D u->dev; + int err; + + if (!dev->started || event !=3D CHR_EVENT_OPENED) { + return; + } + + if (virtio_has_feature(dev->features, VHOST_USER_F_PROTOCOL_FEATURES))= { + err =3D vhost_user_set_protocol_features(dev, dev->protocol_featur= es); + if (err < 0) { + goto fail; + } + } + + vhost_close_slave_channel(dev); + err =3D vhost_setup_slave_channel(dev); + if (err < 0) { + goto fail; + } + + err =3D vhost_dev_reconnect(dev); + if (err < 0) { + goto fail; + } + + return; + +fail: + error_report("Failed to reconnect to backend: %d", err); + qemu_chr_fe_disconnect(u->user->chr); +} + static int vhost_user_backend_init(struct vhost_dev *dev, void *opaque) { uint64_t features, protocol_features; @@ -1348,6 +1394,19 @@ static int vhost_user_backend_init(struct vhost_dev = *dev, void *opaque) u->dev =3D dev; dev->opaque =3D u; =20 + /* We expect the socket is already connected, but Chardev with reconne= ct + * option postpones connect till machine init done event. If this is t= he + * case, then the connect will be forced. */ + if (!qemu_chr_fe_backend_open(u->user->chr) && + qemu_chr_fe_wait_connected(u->user->chr, NULL) < 0) { + return -1; + } + + /* Set reconnection handler. */ + qemu_chr_fe_set_handlers(u->user->chr, NULL, NULL, + vhost_user_reconnect_handler, + NULL, u, NULL, false); + err =3D vhost_user_get_features(dev, &features); if (err < 0) { return err; @@ -1430,11 +1489,7 @@ static int vhost_user_backend_cleanup(struct vhost_d= ev *dev) postcopy_remove_notifier(&u->postcopy_notifier); u->postcopy_notifier.notify =3D NULL; } - if (u->slave_fd >=3D 0) { - qemu_set_fd_handler(u->slave_fd, NULL, NULL, NULL); - close(u->slave_fd); - u->slave_fd =3D -1; - } + vhost_close_slave_channel(dev); g_free(u->region_rb); u->region_rb =3D NULL; g_free(u->region_rb_offset); diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index 6fcfb87..dbd496b 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -1633,6 +1633,37 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODe= vice *vdev) hdev->vdev =3D NULL; } =20 +int vhost_dev_reconnect(struct vhost_dev *hdev) +{ + int i, r; + + assert(hdev->vhost_ops->backend_type =3D=3D VHOST_BACKEND_TYPE_USER); + assert(hdev->started); + assert(hdev->vhost_ops); + assert(hdev->vdev); + + for (i =3D 0; i < hdev->nvqs; ++i) { + /* Sync internal last avail idx to the device used idx. */ + virtio_queue_restore_last_avail_idx(hdev->vdev, hdev->vq_index + i= ); + } + + r =3D vhost_dev_sync_backend(hdev); + if (r < 0) { + goto fail; + } + + /* Sync previous mask values */ + for (i =3D 0; i < hdev->nvqs; ++i) { + unsigned idx =3D hdev->vq_index + i; + vhost_virtqueue_mask(hdev, hdev->vdev, idx, hdev->vqs[idx].masked); + } + + return 0; + +fail: + return r; +} + int vhost_net_set_backend(struct vhost_dev *hdev, struct vhost_vring_file *file) { diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h index a43db26..c3d375a 100644 --- a/include/hw/virtio/vhost.h +++ b/include/hw/virtio/vhost.h @@ -91,6 +91,7 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque, void vhost_dev_cleanup(struct vhost_dev *hdev); int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev); void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev); +int vhost_dev_reconnect(struct vhost_dev *hdev); int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev); void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vde= v); =20 --=20 2.7.4