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 1534435473590408.4659978558308; Thu, 16 Aug 2018 09:04:33 -0700 (PDT) Received: from localhost ([::1]:56563 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fqKlE-00066T-EK for importer@patchew.org; Thu, 16 Aug 2018 12:04:32 -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 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= 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=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" 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; } =20 -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 =3D BUS(qdev_get_parent_bus(DEVICE(vdev))); VirtioBusState *vbus =3D VIRTIO_BUS(qbus); VirtioBusClass *k =3D VIRTIO_BUS_GET_CLASS(vbus); - hwaddr s, l, a; int r; int vhost_vq_index =3D dev->vhost_ops->vhost_get_vq_index(dev, idx); struct vhost_vring_file file =3D { @@ -960,13 +959,7 @@ static int vhost_virtqueue_start(struct vhost_dev *dev, }; struct VirtQueue *vvq =3D virtio_get_queue(vdev, idx); =20 - a =3D virtio_queue_get_desc_addr(vdev, idx); - if (a =3D=3D 0) { - /* Queue might not be ready for start */ - return 0; - } - - vq->num =3D state.num =3D virtio_queue_get_num(vdev, idx); + state.num =3D virtio_queue_get_num(vdev, idx); r =3D 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 *de= v, } } =20 - vq->desc_size =3D s =3D l =3D virtio_queue_get_desc_size(vdev, idx); - vq->desc_phys =3D a; - vq->desc =3D vhost_memory_map(dev, a, &l, 0); - if (!vq->desc || l !=3D s) { - r =3D -ENOMEM; - goto fail_alloc_desc; - } - vq->avail_size =3D s =3D l =3D virtio_queue_get_avail_size(vdev, idx); - vq->avail_phys =3D a =3D virtio_queue_get_avail_addr(vdev, idx); - vq->avail =3D vhost_memory_map(dev, a, &l, 0); - if (!vq->avail || l !=3D s) { - r =3D -ENOMEM; - goto fail_alloc_avail; - } - vq->used_size =3D s =3D l =3D virtio_queue_get_used_size(vdev, idx); - vq->used_phys =3D a =3D virtio_queue_get_used_addr(vdev, idx); - vq->used =3D vhost_memory_map(dev, a, &l, 1); - if (!vq->used || l !=3D s) { - r =3D -ENOMEM; - goto fail_alloc_used; - } - r =3D vhost_virtqueue_set_addr(dev, vq, vhost_vq_index, dev->log_enabl= ed); if (r < 0) { r =3D -errno; - goto fail_alloc; + goto fail; } =20 file.fd =3D 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 =3D -errno; - goto fail_kick; + goto fail; } =20 /* Clear and discard previous events if any. */ @@ -1042,15 +1013,56 @@ static int vhost_virtqueue_start(struct vhost_dev *= dev, file.fd =3D -1; r =3D dev->vhost_ops->vhost_set_vring_call(dev, &file); if (r) { - goto fail_vector; + goto fail; } } =20 return 0; =20 -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 =3D virtio_queue_get_desc_addr(vdev, idx); + if (a =3D=3D 0) { + /* Queue might not be ready for start */ + return 0; + } + + vq->num =3D virtio_queue_get_num(vdev, idx); + + vq->desc_size =3D s =3D l =3D virtio_queue_get_desc_size(vdev, idx); + vq->desc_phys =3D a; + vq->desc =3D vhost_memory_map(dev, a, &l, 0); + if (!vq->desc || l !=3D s) { + r =3D -ENOMEM; + goto fail_alloc_desc; + } + vq->avail_size =3D s =3D l =3D virtio_queue_get_avail_size(vdev, idx); + vq->avail_phys =3D a =3D virtio_queue_get_avail_addr(vdev, idx); + vq->avail =3D vhost_memory_map(dev, a, &l, 0); + if (!vq->avail || l !=3D s) { + r =3D -ENOMEM; + goto fail_alloc_avail; + } + vq->used_size =3D s =3D l =3D virtio_queue_get_used_size(vdev, idx); + vq->used_phys =3D a =3D virtio_queue_get_used_addr(vdev, idx); + vq->used =3D vhost_memory_map(dev, a, &l, 1); + if (!vq->used || l !=3D s) { + r =3D -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; } =20 + dev->vqs[n].masked =3D true; file.fd =3D event_notifier_get_fd(&vq->masked_notifier); r =3D dev->vhost_ops->vhost_set_vring_call(dev, &file); if (r) { @@ -1417,6 +1430,7 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, Vir= tIODevice *vdev, int n, } else { file.fd =3D event_notifier_get_fd(virtio_queue_get_guest_notifier(= vvq)); } + hdev->vqs[index].masked =3D mask; =20 file.index =3D hdev->vhost_ops->vhost_get_vq_index(hdev, n); r =3D 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 =3D ops; } =20 -/* 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 =3D true; - hdev->vdev =3D vdev; + assert(hdev->vdev); =20 r =3D 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; } =20 r =3D hdev->vhost_ops->vhost_set_mem_table(hdev, hdev->mem); if (r < 0) { - VHOST_OPS_DEBUG("vhost_set_mem_table failed"); r =3D -errno; - goto fail_mem; + goto fail; } + for (i =3D 0; i < hdev->nvqs; ++i) { - r =3D vhost_virtqueue_start(hdev, - vdev, - hdev->vqs + i, - hdev->vq_index + i); + r =3D vhost_virtqueue_sync_backend(hdev, + hdev->vdev, + hdev->vqs + i, + hdev->vq_index + i); if (r < 0) { - goto fail_vq; + goto fail; } } =20 if (hdev->log_enabled) { uint64_t log_base; - - hdev->log_size =3D vhost_get_log_size(hdev); - hdev->log =3D vhost_log_get(hdev->log_size, - vhost_dev_log_is_shared(hdev)); - log_base =3D (uintptr_t)hdev->log->log; - r =3D hdev->vhost_ops->vhost_set_log_base(hdev, - hdev->log_size ? log_base = : 0, - hdev->log); + assert(hdev->log); + log_base =3D hdev->log_size ? (uintptr_t)hdev->log->log : 0; + r =3D hdev->vhost_ops->vhost_set_log_base(hdev, log_base, hdev->lo= g); if (r < 0) { - VHOST_OPS_DEBUG("vhost_set_log_base failed"); r =3D -errno; - goto fail_log; + goto fail; } } =20 @@ -1546,20 +1545,65 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIOD= evice *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 =3D true; + hdev->vdev =3D vdev; + + if (vhost_dev_has_iommu(hdev)) { + memory_listener_register(&hdev->iommu_listener, vdev->dma_as); + } + + for (i =3D 0; i < hdev->nvqs; ++i) { + r =3D 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 =3D vhost_get_log_size(hdev); + hdev->log =3D vhost_log_get(hdev->log_size, + vhost_dev_log_is_shared(hdev)); + } + + r =3D 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 >=3D 0) { vhost_virtqueue_stop(hdev, vdev, hdev->vqs + i, hdev->vq_index + i); } - i =3D hdev->nvqs; - -fail_mem: -fail_features: =20 hdev->started =3D 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; }; --=20 2.7.4