From patchwork Thu Aug 16 15:32:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yury Kotov X-Patchwork-Id: 10567859 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 981A5913 for ; Thu, 16 Aug 2018 16:45:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 877E52B53C for ; Thu, 16 Aug 2018 16:45:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7C1852B544; Thu, 16 Aug 2018 16:45:29 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 3107E2B53C for ; Thu, 16 Aug 2018 16:45:29 +0000 (UTC) Received: from localhost ([::1]:56963 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fqLOq-0006be-G9 for patchwork-qemu-devel@patchwork.kernel.org; Thu, 16 Aug 2018 12:45:28 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38001) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fqKGg-000451-TM for qemu-devel@nongnu.org; Thu, 16 Aug 2018 11:32:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fqKGg-0002oI-1G for qemu-devel@nongnu.org; Thu, 16 Aug 2018 11:32:58 -0400 Received: from forwardcorp1o.cmail.yandex.net ([2a02:6b8:0:1a72::290]:46256) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fqKGf-0002n4-NA for qemu-devel@nongnu.org; Thu, 16 Aug 2018 11:32:57 -0400 Received: from mxbackcorp1o.mail.yandex.net (mxbackcorp1o.mail.yandex.net [IPv6:2a02:6b8:0:1a2d::301]) by forwardcorp1o.cmail.yandex.net (Yandex) with ESMTP id 986AD216C8; Thu, 16 Aug 2018 18:32:55 +0300 (MSK) Received: from smtpcorp1p.mail.yandex.net (smtpcorp1p.mail.yandex.net [2a02:6b8:0:1472:2741:0:8b6:10]) by mxbackcorp1o.mail.yandex.net (nwsmtp/Yandex) with ESMTP id TJcmgZIVVP-WtZeNgXV; Thu, 16 Aug 2018 18:32:55 +0300 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex-team.ru; s=default; t=1534433575; bh=0QIzaDdah3tsa+JEcxogjQ/e94+YiuZgK7heIv2c1/4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=R1aOlx81QQ356mBuKo38tU5g5Sqqsh/4DQrn4HvUPdrQUEbJpjDC8KXV20vtofN5C DkIU2xU73JMPtTW+s7HKu1pkiYBX+pjQ8yTx4NaOzaL65OjifKhX15XQewg+ALXCEq 5W36f1SPMrg24LbmEWV/5aSKRnczxgIsZmGQRskM= 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-WtXuDL3t; Thu, 16 Aug 2018 18:32:55 +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=1534433575; bh=0QIzaDdah3tsa+JEcxogjQ/e94+YiuZgK7heIv2c1/4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=R1aOlx81QQ356mBuKo38tU5g5Sqqsh/4DQrn4HvUPdrQUEbJpjDC8KXV20vtofN5C DkIU2xU73JMPtTW+s7HKu1pkiYBX+pjQ8yTx4NaOzaL65OjifKhX15XQewg+ALXCEq 5W36f1SPMrg24LbmEWV/5aSKRnczxgIsZmGQRskM= 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:41 +0300 Message-Id: <1534433563-30865-2-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:1a72::290 Subject: [Qemu-devel] [PATCH 1/3] chardev: prevent extra connection attempt in tcp_chr_machine_done_hook 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_Lureau?= , Paolo Bonzini , Evgeny Yakovlev , "Michael S. Tsirkin" Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Usually chardev connects to specified address during the initialization. But if reconnect_time is specified then connection will be postponed until machine done event. Thus if reconnect is specified and some device forces connection during initialization, tcp_chr_machine_done_hook will do useless connection attempt. So add a check to prevent it. Signed-off-by: Yury Kotov Signed-off-by: Evgeny Yakovlev --- chardev/char-socket.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/chardev/char-socket.c b/chardev/char-socket.c index efbad6e..116dcc4 100644 --- a/chardev/char-socket.c +++ b/chardev/char-socket.c @@ -1165,7 +1165,10 @@ static int tcp_chr_machine_done_hook(Chardev *chr) { SocketChardev *s = SOCKET_CHARDEV(chr); - if (s->reconnect_time) { + /* It's possible that connection was established during the device + * initialization. So check if the socket is already connected to + * prevent extra connection attempt. */ + if (!s->connected && s->reconnect_time) { tcp_chr_connect_async(chr); } From patchwork Thu Aug 16 15:32:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yury Kotov X-Patchwork-Id: 10567741 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D6040139A for ; Thu, 16 Aug 2018 16:03:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C3D352B4F7 for ; Thu, 16 Aug 2018 16:03:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B64A52B4F9; Thu, 16 Aug 2018 16:03:54 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 0AF922B4F7 for ; Thu, 16 Aug 2018 16:03:54 +0000 (UTC) Received: from localhost ([::1]:56563 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fqKkb-00066T-9S for patchwork-qemu-devel@patchwork.kernel.org; Thu, 16 Aug 2018 12:03:53 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38028) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fqKGi-00047m-HW 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-0002ou-8a for qemu-devel@nongnu.org; Thu, 16 Aug 2018 11:33:00 -0400 Received: from forwardcorp1j.cmail.yandex.net ([2a02:6b8:0:1630::190]:52981) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fqKGg-0002nW-R0 for qemu-devel@nongnu.org; Thu, 16 Aug 2018 11:32:59 -0400 Received: from mxbackcorp1g.mail.yandex.net (mxbackcorp1g.mail.yandex.net [IPv6:2a02:6b8:0:1402::301]) by forwardcorp1j.cmail.yandex.net (Yandex) with ESMTP id BAB3020EB9; Thu, 16 Aug 2018 18:32:56 +0300 (MSK) Received: from smtpcorp1p.mail.yandex.net (smtpcorp1p.mail.yandex.net [2a02:6b8:0:1472:2741:0:8b6:10]) by mxbackcorp1g.mail.yandex.net (nwsmtp/Yandex) with ESMTP id e2HkxUoNnm-Wu8Gg8vH; Thu, 16 Aug 2018 18:32:56 +0300 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex-team.ru; s=default; t=1534433576; bh=phe6xUcGiMXipirU647jqg60GjWfYuEqHpHP1dYNfBg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=z3toBJ+5wnbTMNtauDT6vnUVCBrqr0CKb4LFEWL6GtJ704Ca0Sf5XQZH6KbMUfhec AWwnmjGmgF566lLxXFnE9NV82vzIE3lqbEqdTMd0D9HuLSVlHEV0jWz7x0Hm7okBNO 6jK99BxmJY/w/GR2AZhXCYAU0QZYBfiyAAjKOGP4= 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-WuXKruEi; Thu, 16 Aug 2018 18:32:56 +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=1534433576; bh=phe6xUcGiMXipirU647jqg60GjWfYuEqHpHP1dYNfBg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=z3toBJ+5wnbTMNtauDT6vnUVCBrqr0CKb4LFEWL6GtJ704Ca0Sf5XQZH6KbMUfhec AWwnmjGmgF566lLxXFnE9NV82vzIE3lqbEqdTMd0D9HuLSVlHEV0jWz7x0Hm7okBNO 6jK99BxmJY/w/GR2AZhXCYAU0QZYBfiyAAjKOGP4= 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:42 +0300 Message-Id: <1534433563-30865-3-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 2/3] vhost: refactor vhost_dev_start and vhost_virtqueue_start 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_Lureau?= , Paolo Bonzini , Evgeny Yakovlev , "Michael S. Tsirkin" Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP vhost_dev_start and vhost_virtqueue_start do two things: 1. Initialize its own structs vhost_dev and vhost_virtqueue, 2. Sync with vhost backend. It's ok, but we want to do sync part separately. This refactoring is needed for the next patch, which adds reconnect support for vhost-user. So, 1. Move initialization part of vhost_dev_start which syncs with backend to the separate function: vhost_dev_sync_backend. 2. Divide vhost_virtqueue_start into two functions: * vhost_virtqueue_setup: prepares vhost_virtqueue to work with corresponding VirtQueue, * vhost_virtqueue_sync_backend: syncs vhost_virtqueue and backend. Signed-off-by: Yury Kotov Signed-off-by: Evgeny Yakovlev --- hw/virtio/vhost.c | 192 ++++++++++++++++++++++++++++------------------ include/hw/virtio/vhost.h | 1 + 2 files changed, 119 insertions(+), 74 deletions(-) diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index d4cb589..6fcfb87 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -941,15 +941,14 @@ out: return ret; } -static int vhost_virtqueue_start(struct vhost_dev *dev, - struct VirtIODevice *vdev, - struct vhost_virtqueue *vq, - unsigned idx) +static int vhost_virtqueue_sync_backend(struct vhost_dev *dev, + struct VirtIODevice *vdev, + struct vhost_virtqueue *vq, + unsigned idx) { BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); VirtioBusState *vbus = VIRTIO_BUS(qbus); VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus); - hwaddr s, l, a; int r; int vhost_vq_index = dev->vhost_ops->vhost_get_vq_index(dev, idx); struct vhost_vring_file file = { @@ -960,13 +959,7 @@ static int vhost_virtqueue_start(struct vhost_dev *dev, }; struct VirtQueue *vvq = virtio_get_queue(vdev, idx); - a = virtio_queue_get_desc_addr(vdev, idx); - if (a == 0) { - /* Queue might not be ready for start */ - return 0; - } - - vq->num = state.num = virtio_queue_get_num(vdev, idx); + state.num = virtio_queue_get_num(vdev, idx); r = dev->vhost_ops->vhost_set_vring_num(dev, &state); if (r) { VHOST_OPS_DEBUG("vhost_set_vring_num failed"); @@ -989,32 +982,10 @@ static int vhost_virtqueue_start(struct vhost_dev *dev, } } - vq->desc_size = s = l = virtio_queue_get_desc_size(vdev, idx); - vq->desc_phys = a; - vq->desc = vhost_memory_map(dev, a, &l, 0); - if (!vq->desc || l != s) { - r = -ENOMEM; - goto fail_alloc_desc; - } - vq->avail_size = s = l = virtio_queue_get_avail_size(vdev, idx); - vq->avail_phys = a = virtio_queue_get_avail_addr(vdev, idx); - vq->avail = vhost_memory_map(dev, a, &l, 0); - if (!vq->avail || l != s) { - r = -ENOMEM; - goto fail_alloc_avail; - } - vq->used_size = s = l = virtio_queue_get_used_size(vdev, idx); - vq->used_phys = a = virtio_queue_get_used_addr(vdev, idx); - vq->used = vhost_memory_map(dev, a, &l, 1); - if (!vq->used || l != s) { - r = -ENOMEM; - goto fail_alloc_used; - } - r = vhost_virtqueue_set_addr(dev, vq, vhost_vq_index, dev->log_enabled); if (r < 0) { r = -errno; - goto fail_alloc; + goto fail; } file.fd = event_notifier_get_fd(virtio_queue_get_host_notifier(vvq)); @@ -1022,7 +993,7 @@ static int vhost_virtqueue_start(struct vhost_dev *dev, if (r) { VHOST_OPS_DEBUG("vhost_set_vring_kick failed"); r = -errno; - goto fail_kick; + goto fail; } /* Clear and discard previous events if any. */ @@ -1042,15 +1013,56 @@ static int vhost_virtqueue_start(struct vhost_dev *dev, file.fd = -1; r = dev->vhost_ops->vhost_set_vring_call(dev, &file); if (r) { - goto fail_vector; + goto fail; } } return 0; -fail_vector: -fail_kick: -fail_alloc: +fail: + return r; +} + +static int vhost_virtqueue_setup(struct vhost_dev *dev, + struct VirtIODevice *vdev, + struct vhost_virtqueue *vq, + unsigned idx) +{ + hwaddr s, l, a; + int r; + + a = virtio_queue_get_desc_addr(vdev, idx); + if (a == 0) { + /* Queue might not be ready for start */ + return 0; + } + + vq->num = virtio_queue_get_num(vdev, idx); + + vq->desc_size = s = l = virtio_queue_get_desc_size(vdev, idx); + vq->desc_phys = a; + vq->desc = vhost_memory_map(dev, a, &l, 0); + if (!vq->desc || l != s) { + r = -ENOMEM; + goto fail_alloc_desc; + } + vq->avail_size = s = l = virtio_queue_get_avail_size(vdev, idx); + vq->avail_phys = a = virtio_queue_get_avail_addr(vdev, idx); + vq->avail = vhost_memory_map(dev, a, &l, 0); + if (!vq->avail || l != s) { + r = -ENOMEM; + goto fail_alloc_avail; + } + vq->used_size = s = l = virtio_queue_get_used_size(vdev, idx); + vq->used_phys = a = virtio_queue_get_used_addr(vdev, idx); + vq->used = vhost_memory_map(dev, a, &l, 1); + if (!vq->used || l != s) { + r = -ENOMEM; + goto fail_alloc_used; + } + + return 0; + vhost_memory_unmap(dev, vq->used, virtio_queue_get_used_size(vdev, idx), 0, 0); fail_alloc_used: @@ -1158,6 +1170,7 @@ static int vhost_virtqueue_init(struct vhost_dev *dev, return r; } + dev->vqs[n].masked = true; file.fd = event_notifier_get_fd(&vq->masked_notifier); r = dev->vhost_ops->vhost_set_vring_call(dev, &file); if (r) { @@ -1417,6 +1430,7 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n, } else { file.fd = event_notifier_get_fd(virtio_queue_get_guest_notifier(vvq)); } + hdev->vqs[index].masked = mask; file.index = hdev->vhost_ops->vhost_get_vq_index(hdev, n); r = hdev->vhost_ops->vhost_set_vring_call(hdev, &file); @@ -1483,56 +1497,41 @@ void vhost_dev_set_config_notifier(struct vhost_dev *hdev, hdev->config_ops = ops; } -/* Host notifiers must be enabled at this point. */ -int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev) +static int vhost_dev_sync_backend(struct vhost_dev *hdev) { int i, r; - - /* should only be called after backend is connected */ assert(hdev->vhost_ops); - - hdev->started = true; - hdev->vdev = vdev; + assert(hdev->vdev); r = vhost_dev_set_features(hdev, hdev->log_enabled); if (r < 0) { - goto fail_features; - } - - if (vhost_dev_has_iommu(hdev)) { - memory_listener_register(&hdev->iommu_listener, vdev->dma_as); + goto fail; } r = hdev->vhost_ops->vhost_set_mem_table(hdev, hdev->mem); if (r < 0) { - VHOST_OPS_DEBUG("vhost_set_mem_table failed"); r = -errno; - goto fail_mem; + goto fail; } + for (i = 0; i < hdev->nvqs; ++i) { - r = vhost_virtqueue_start(hdev, - vdev, - hdev->vqs + i, - hdev->vq_index + i); + r = vhost_virtqueue_sync_backend(hdev, + hdev->vdev, + hdev->vqs + i, + hdev->vq_index + i); if (r < 0) { - goto fail_vq; + goto fail; } } if (hdev->log_enabled) { uint64_t log_base; - - hdev->log_size = vhost_get_log_size(hdev); - hdev->log = vhost_log_get(hdev->log_size, - vhost_dev_log_is_shared(hdev)); - log_base = (uintptr_t)hdev->log->log; - r = hdev->vhost_ops->vhost_set_log_base(hdev, - hdev->log_size ? log_base : 0, - hdev->log); + assert(hdev->log); + log_base = hdev->log_size ? (uintptr_t)hdev->log->log : 0; + r = hdev->vhost_ops->vhost_set_log_base(hdev, log_base, hdev->log); if (r < 0) { - VHOST_OPS_DEBUG("vhost_set_log_base failed"); r = -errno; - goto fail_log; + goto fail; } } @@ -1546,20 +1545,65 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev) vhost_device_iotlb_miss(hdev, vq->used_phys, true); } } + return 0; -fail_log: + +fail: + return r; +} + +/* Host notifiers must be enabled at this point. */ +int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev) +{ + int i, r; + + /* should only be called after backend is connected */ + assert(hdev->vhost_ops); + + hdev->started = true; + hdev->vdev = vdev; + + if (vhost_dev_has_iommu(hdev)) { + memory_listener_register(&hdev->iommu_listener, vdev->dma_as); + } + + for (i = 0; i < hdev->nvqs; ++i) { + r = vhost_virtqueue_setup(hdev, + vdev, + hdev->vqs + i, + hdev->vq_index + i); + if (r < 0) { + goto fail_vq; + } + } + + if (hdev->log_enabled) { + hdev->log_size = vhost_get_log_size(hdev); + hdev->log = vhost_log_get(hdev->log_size, + vhost_dev_log_is_shared(hdev)); + } + + r = vhost_dev_sync_backend(hdev); + if (r < 0) { + goto fail_sync; + } + + return 0; + +fail_sync: vhost_log_put(hdev, false); + fail_vq: + if (vhost_dev_has_iommu(hdev)) { + memory_listener_unregister(&hdev->iommu_listener); + } + while (--i >= 0) { vhost_virtqueue_stop(hdev, vdev, hdev->vqs + i, hdev->vq_index + i); } - i = hdev->nvqs; - -fail_mem: -fail_features: hdev->started = false; return r; diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h index a7f449f..a43db26 100644 --- a/include/hw/virtio/vhost.h +++ b/include/hw/virtio/vhost.h @@ -20,6 +20,7 @@ struct vhost_virtqueue { unsigned avail_size; unsigned long long used_phys; unsigned used_size; + bool masked; EventNotifier masked_notifier; struct vhost_dev *dev; }; From patchwork Thu Aug 16 15:32:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yury Kotov X-Patchwork-Id: 10567817 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A924513B4 for ; Thu, 16 Aug 2018 16:37:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 97E8D2B550 for ; Thu, 16 Aug 2018 16:37:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8BF852B555; Thu, 16 Aug 2018 16:37:14 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id A61132B550 for ; Thu, 16 Aug 2018 16:37:13 +0000 (UTC) Received: from localhost ([::1]:56904 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fqLGr-00081v-0C for patchwork-qemu-devel@patchwork.kernel.org; Thu, 16 Aug 2018 12:37:13 -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 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= 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= 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_Lureau?= , Paolo Bonzini , Evgeny Yakovlev , "Michael S. Tsirkin" Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP 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; } +static void vhost_close_slave_channel(struct vhost_dev *dev) +{ + struct vhost_user *u = dev->opaque; + + if (u->slave_fd >= 0) { + qemu_set_fd_handler(u->slave_fd, NULL, NULL, NULL); + close(u->slave_fd); + u->slave_fd = -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(NotifierWithReturn *notifier, return 0; } +static void vhost_user_reconnect_handler(void *opaque, int event) +{ + struct vhost_user *u = opaque; + struct vhost_dev *dev = u->dev; + int err; + + if (!dev->started || event != CHR_EVENT_OPENED) { + return; + } + + if (virtio_has_feature(dev->features, VHOST_USER_F_PROTOCOL_FEATURES)) { + err = vhost_user_set_protocol_features(dev, dev->protocol_features); + if (err < 0) { + goto fail; + } + } + + vhost_close_slave_channel(dev); + err = vhost_setup_slave_channel(dev); + if (err < 0) { + goto fail; + } + + err = 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 = dev; dev->opaque = u; + /* We expect the socket is already connected, but Chardev with reconnect + * option postpones connect till machine init done event. If this is the + * 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 = vhost_user_get_features(dev, &features); if (err < 0) { return err; @@ -1430,11 +1489,7 @@ static int vhost_user_backend_cleanup(struct vhost_dev *dev) postcopy_remove_notifier(&u->postcopy_notifier); u->postcopy_notifier.notify = NULL; } - if (u->slave_fd >= 0) { - qemu_set_fd_handler(u->slave_fd, NULL, NULL, NULL); - close(u->slave_fd); - u->slave_fd = -1; - } + vhost_close_slave_channel(dev); g_free(u->region_rb); u->region_rb = 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, VirtIODevice *vdev) hdev->vdev = NULL; } +int vhost_dev_reconnect(struct vhost_dev *hdev) +{ + int i, r; + + assert(hdev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER); + assert(hdev->started); + assert(hdev->vhost_ops); + assert(hdev->vdev); + + for (i = 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 = vhost_dev_sync_backend(hdev); + if (r < 0) { + goto fail; + } + + /* Sync previous mask values */ + for (i = 0; i < hdev->nvqs; ++i) { + unsigned idx = 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 *vdev);