From nobody Sat Nov 1 22:28:29 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; 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=intel.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1527158159527212.01508964950938; Thu, 24 May 2018 03:35:59 -0700 (PDT) Received: from localhost ([::1]:37672 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fLnb8-0004oy-75 for importer@patchew.org; Thu, 24 May 2018 06:35:54 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38421) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fLnYo-0003Sh-4r for qemu-devel@nongnu.org; Thu, 24 May 2018 06:33:32 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fLnYl-00054D-Ri for qemu-devel@nongnu.org; Thu, 24 May 2018 06:33:30 -0400 Received: from mga17.intel.com ([192.55.52.151]:6501) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fLnYl-00053t-Gy for qemu-devel@nongnu.org; Thu, 24 May 2018 06:33:27 -0400 Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 24 May 2018 03:33:26 -0700 Received: from debian.sh.intel.com ([10.67.104.203]) by orsmga002.jf.intel.com with ESMTP; 24 May 2018 03:33:25 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.49,436,1520924400"; d="scan'208";a="61316258" From: Tiwei Bie To: mst@redhat.com, jasowang@redhat.com, qemu-devel@nongnu.org, virtio-dev@lists.oasis-open.org Date: Thu, 24 May 2018 18:33:33 +0800 Message-Id: <20180524103336.21233-4-tiwei.bie@intel.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180524103336.21233-1-tiwei.bie@intel.com> References: <20180524103336.21233-1-tiwei.bie@intel.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 192.55.52.151 Subject: [Qemu-devel] [PATCH 3/6] vhost-user: introduce shared vhost-user state 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: tiwei.bie@intel.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" When multi queue is enabled e.g. for a virtio-net device, each queue pair will have a vhost_dev, and the only thing shared between vhost devs currently is the chardev. This patch introduces a vhost-user state structure which will be shared by all vhost devs of the same virtio device. Signed-off-by: Tiwei Bie Signed-off-by: Michael S. Tsirkin --- backends/cryptodev-vhost-user.c | 20 ++++++++++++- hw/block/vhost-user-blk.c | 22 ++++++++++++++- hw/scsi/vhost-user-scsi.c | 20 ++++++++++++- hw/virtio/Makefile.objs | 2 +- hw/virtio/vhost-stub.c | 10 +++++++ hw/virtio/vhost-user.c | 31 ++++++++++++++------ include/hw/virtio/vhost-user-blk.h | 2 ++ include/hw/virtio/vhost-user-scsi.h | 2 ++ include/hw/virtio/vhost-user.h | 20 +++++++++++++ net/vhost-user.c | 44 +++++++++++++++++++++++------ 10 files changed, 152 insertions(+), 21 deletions(-) create mode 100644 include/hw/virtio/vhost-user.h diff --git a/backends/cryptodev-vhost-user.c b/backends/cryptodev-vhost-use= r.c index 862d4f2580..d52daccfcd 100644 --- a/backends/cryptodev-vhost-user.c +++ b/backends/cryptodev-vhost-user.c @@ -26,6 +26,7 @@ #include "qapi/error.h" #include "qapi/qmp/qerror.h" #include "qemu/error-report.h" +#include "hw/virtio/vhost-user.h" #include "standard-headers/linux/virtio_crypto.h" #include "sysemu/cryptodev-vhost.h" #include "chardev/char-fe.h" @@ -46,6 +47,7 @@ typedef struct CryptoDevBackendVhostUser { CryptoDevBackend parent_obj; =20 + VhostUserState *vhost_user; CharBackend chr; char *chr_name; bool opened; @@ -102,7 +104,7 @@ cryptodev_vhost_user_start(int queues, continue; } =20 - options.opaque =3D &s->chr; + options.opaque =3D s->vhost_user; options.backend_type =3D VHOST_BACKEND_TYPE_USER; options.cc =3D b->conf.peers.ccs[i]; s->vhost_crypto[i] =3D cryptodev_vhost_init(&options); @@ -185,6 +187,7 @@ static void cryptodev_vhost_user_init( size_t i; Error *local_err =3D NULL; Chardev *chr; + VhostUserState *user; CryptoDevBackendClient *cc; CryptoDevBackendVhostUser *s =3D CRYPTODEV_BACKEND_VHOST_USER(backend); @@ -215,6 +218,15 @@ static void cryptodev_vhost_user_init( } } =20 + user =3D vhost_user_init(); + if (!user) { + error_setg(errp, "Failed to init vhost_user"); + return; + } + + user->chr =3D &s->chr; + s->vhost_user =3D user; + qemu_chr_fe_set_handlers(&s->chr, NULL, NULL, cryptodev_vhost_user_event, NULL, s, NULL, true); =20 @@ -299,6 +311,12 @@ static void cryptodev_vhost_user_cleanup( backend->conf.peers.ccs[i] =3D NULL; } } + + if (s->vhost_user) { + vhost_user_cleanup(s->vhost_user); + g_free(s->vhost_user); + s->vhost_user =3D NULL; + } } =20 static void cryptodev_vhost_user_set_chardev(Object *obj, diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c index 975eae6211..7c3fa8bb1c 100644 --- a/hw/block/vhost-user-blk.c +++ b/hw/block/vhost-user-blk.c @@ -226,6 +226,7 @@ static void vhost_user_blk_device_realize(DeviceState *= dev, Error **errp) { VirtIODevice *vdev =3D VIRTIO_DEVICE(dev); VHostUserBlk *s =3D VHOST_USER_BLK(vdev); + VhostUserState *user; int i, ret; =20 if (!s->chardev.chr) { @@ -243,6 +244,15 @@ static void vhost_user_blk_device_realize(DeviceState = *dev, Error **errp) return; } =20 + user =3D vhost_user_init(); + if (!user) { + error_setg(errp, "vhost-user-blk: failed to init vhost_user"); + return; + } + + user->chr =3D &s->chardev; + s->vhost_user =3D user; + virtio_init(vdev, "virtio-blk", VIRTIO_ID_BLOCK, sizeof(struct virtio_blk_config)); =20 @@ -258,7 +268,7 @@ static void vhost_user_blk_device_realize(DeviceState *= dev, Error **errp) =20 vhost_dev_set_config_notifier(&s->dev, &blk_ops); =20 - ret =3D vhost_dev_init(&s->dev, &s->chardev, VHOST_BACKEND_TYPE_USER, = 0); + ret =3D vhost_dev_init(&s->dev, s->vhost_user, VHOST_BACKEND_TYPE_USER= , 0); if (ret < 0) { error_setg(errp, "vhost-user-blk: vhost initialization failed: %s", strerror(-ret)); @@ -283,6 +293,10 @@ vhost_err: virtio_err: g_free(s->dev.vqs); virtio_cleanup(vdev); + + vhost_user_cleanup(user); + g_free(user); + s->vhost_user =3D NULL; } =20 static void vhost_user_blk_device_unrealize(DeviceState *dev, Error **errp) @@ -294,6 +308,12 @@ static void vhost_user_blk_device_unrealize(DeviceStat= e *dev, Error **errp) vhost_dev_cleanup(&s->dev); g_free(s->dev.vqs); virtio_cleanup(vdev); + + if (s->vhost_user) { + vhost_user_cleanup(s->vhost_user); + g_free(s->vhost_user); + s->vhost_user =3D NULL; + } } =20 static void vhost_user_blk_instance_init(Object *obj) diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c index 9389ed48e0..9355cfdf07 100644 --- a/hw/scsi/vhost-user-scsi.c +++ b/hw/scsi/vhost-user-scsi.c @@ -69,6 +69,7 @@ static void vhost_user_scsi_realize(DeviceState *dev, Err= or **errp) VirtIOSCSICommon *vs =3D VIRTIO_SCSI_COMMON(dev); VHostUserSCSI *s =3D VHOST_USER_SCSI(dev); VHostSCSICommon *vsc =3D VHOST_SCSI_COMMON(s); + VhostUserState *user; Error *err =3D NULL; int ret; =20 @@ -85,19 +86,30 @@ static void vhost_user_scsi_realize(DeviceState *dev, E= rror **errp) return; } =20 + user =3D vhost_user_init(); + if (!user) { + error_setg(errp, "vhost-user-scsi: failed to init vhost_user"); + return; + } + user->chr =3D &vs->conf.chardev; + vsc->dev.nvqs =3D 2 + vs->conf.num_queues; vsc->dev.vqs =3D g_new(struct vhost_virtqueue, vsc->dev.nvqs); vsc->dev.vq_index =3D 0; vsc->dev.backend_features =3D 0; =20 - ret =3D vhost_dev_init(&vsc->dev, (void *)&vs->conf.chardev, + ret =3D vhost_dev_init(&vsc->dev, user, VHOST_BACKEND_TYPE_USER, 0); if (ret < 0) { error_setg(errp, "vhost-user-scsi: vhost initialization failed: %s= ", strerror(-ret)); + vhost_user_cleanup(user); + g_free(user); return; } =20 + s->vhost_user =3D user; + /* Channel and lun both are 0 for bootable vhost-user-scsi disk */ vsc->channel =3D 0; vsc->lun =3D 0; @@ -117,6 +129,12 @@ static void vhost_user_scsi_unrealize(DeviceState *dev= , Error **errp) g_free(vsc->dev.vqs); =20 virtio_scsi_common_unrealize(dev, errp); + + if (s->vhost_user) { + vhost_user_cleanup(s->vhost_user); + g_free(s->vhost_user); + s->vhost_user =3D NULL; + } } =20 static uint64_t vhost_user_scsi_get_features(VirtIODevice *vdev, diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs index 765d363c1f..030969e28c 100644 --- a/hw/virtio/Makefile.objs +++ b/hw/virtio/Makefile.objs @@ -11,5 +11,5 @@ obj-y +=3D virtio-crypto.o obj-$(CONFIG_VIRTIO_PCI) +=3D virtio-crypto-pci.o endif =20 -common-obj-$(call lnot,$(CONFIG_LINUX)) +=3D vhost-stub.o +common-obj-$(call lnot,$(call land,$(CONFIG_VIRTIO),$(CONFIG_LINUX))) +=3D= vhost-stub.o common-obj-$(CONFIG_ALL) +=3D vhost-stub.o diff --git a/hw/virtio/vhost-stub.c b/hw/virtio/vhost-stub.c index 2d76cdebdc..049089b5e2 100644 --- a/hw/virtio/vhost-stub.c +++ b/hw/virtio/vhost-stub.c @@ -1,7 +1,17 @@ #include "qemu/osdep.h" #include "hw/virtio/vhost.h" +#include "hw/virtio/vhost-user.h" =20 bool vhost_has_free_slot(void) { return true; } + +VhostUserState *vhost_user_init(void) +{ + return NULL; +} + +void vhost_user_cleanup(VhostUserState *user) +{ +} diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c index 75a3faef2a..70b9610c87 100644 --- a/hw/virtio/vhost-user.c +++ b/hw/virtio/vhost-user.c @@ -11,6 +11,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "hw/virtio/vhost.h" +#include "hw/virtio/vhost-user.h" #include "hw/virtio/vhost-backend.h" #include "hw/virtio/virtio-net.h" #include "chardev/char-fe.h" @@ -175,7 +176,8 @@ static VhostUserMsg m __attribute__ ((unused)); =20 struct vhost_user { struct vhost_dev *dev; - CharBackend *chr; + /* Shared between vhost devs of the same virtio device */ + VhostUserState *user; int slave_fd; NotifierWithReturn postcopy_notifier; struct PostCopyFD postcopy_fd; @@ -201,7 +203,7 @@ static bool ioeventfd_enabled(void) static int vhost_user_read(struct vhost_dev *dev, VhostUserMsg *msg) { struct vhost_user *u =3D dev->opaque; - CharBackend *chr =3D u->chr; + CharBackend *chr =3D u->user->chr; uint8_t *p =3D (uint8_t *) msg; int r, size =3D VHOST_USER_HDR_SIZE; =20 @@ -287,7 +289,7 @@ static int vhost_user_write(struct vhost_dev *dev, Vhos= tUserMsg *msg, int *fds, int fd_num) { struct vhost_user *u =3D dev->opaque; - CharBackend *chr =3D u->chr; + CharBackend *chr =3D u->user->chr; int ret, size =3D VHOST_USER_HDR_SIZE + msg->hdr.size; =20 /* @@ -1090,7 +1092,7 @@ static int vhost_user_postcopy_waker(struct PostCopyF= D *pcfd, RAMBlock *rb, static int vhost_user_postcopy_advise(struct vhost_dev *dev, Error **errp) { struct vhost_user *u =3D dev->opaque; - CharBackend *chr =3D u->chr; + CharBackend *chr =3D u->user->chr; int ufd; VhostUserMsg msg =3D { .hdr.request =3D VHOST_USER_POSTCOPY_ADVISE, @@ -1228,7 +1230,7 @@ static int vhost_user_postcopy_notifier(NotifierWithR= eturn *notifier, return 0; } =20 -static int vhost_user_init(struct vhost_dev *dev, void *opaque) +static int vhost_user_backend_init(struct vhost_dev *dev, void *opaque) { uint64_t features, protocol_features; struct vhost_user *u; @@ -1237,7 +1239,7 @@ static int vhost_user_init(struct vhost_dev *dev, voi= d *opaque) assert(dev->vhost_ops->backend_type =3D=3D VHOST_BACKEND_TYPE_USER); =20 u =3D g_new0(struct vhost_user, 1); - u->chr =3D opaque; + u->user =3D opaque; u->slave_fd =3D -1; u->dev =3D dev; dev->opaque =3D u; @@ -1313,7 +1315,7 @@ static int vhost_user_init(struct vhost_dev *dev, voi= d *opaque) return 0; } =20 -static int vhost_user_cleanup(struct vhost_dev *dev) +static int vhost_user_backend_cleanup(struct vhost_dev *dev) { struct vhost_user *u; =20 @@ -1637,10 +1639,21 @@ static bool vhost_user_mem_section_filter(struct vh= ost_dev *dev, return result; } =20 +VhostUserState *vhost_user_init(void) +{ + VhostUserState *user =3D g_new0(struct VhostUserState, 1); + + return user; +} + +void vhost_user_cleanup(VhostUserState *user) +{ +} + const VhostOps user_ops =3D { .backend_type =3D VHOST_BACKEND_TYPE_USER, - .vhost_backend_init =3D vhost_user_init, - .vhost_backend_cleanup =3D vhost_user_cleanup, + .vhost_backend_init =3D vhost_user_backend_init, + .vhost_backend_cleanup =3D vhost_user_backend_cleanup, .vhost_backend_memslots_limit =3D vhost_user_memslots_limit, .vhost_set_log_base =3D vhost_user_set_log_base, .vhost_set_mem_table =3D vhost_user_set_mem_table, diff --git a/include/hw/virtio/vhost-user-blk.h b/include/hw/virtio/vhost-u= ser-blk.h index 5804cc904a..f1258ae545 100644 --- a/include/hw/virtio/vhost-user-blk.h +++ b/include/hw/virtio/vhost-user-blk.h @@ -21,6 +21,7 @@ #include "hw/block/block.h" #include "chardev/char-fe.h" #include "hw/virtio/vhost.h" +#include "hw/virtio/vhost-user.h" =20 #define TYPE_VHOST_USER_BLK "vhost-user-blk" #define VHOST_USER_BLK(obj) \ @@ -36,6 +37,7 @@ typedef struct VHostUserBlk { uint32_t config_wce; uint32_t config_ro; struct vhost_dev dev; + VhostUserState *vhost_user; } VHostUserBlk; =20 #endif diff --git a/include/hw/virtio/vhost-user-scsi.h b/include/hw/virtio/vhost-= user-scsi.h index 01861f78d0..3ec34ae867 100644 --- a/include/hw/virtio/vhost-user-scsi.h +++ b/include/hw/virtio/vhost-user-scsi.h @@ -21,6 +21,7 @@ #include "hw/qdev.h" #include "hw/virtio/virtio-scsi.h" #include "hw/virtio/vhost.h" +#include "hw/virtio/vhost-user.h" #include "hw/virtio/vhost-scsi-common.h" =20 #define TYPE_VHOST_USER_SCSI "vhost-user-scsi" @@ -30,6 +31,7 @@ typedef struct VHostUserSCSI { VHostSCSICommon parent_obj; uint64_t host_features; + VhostUserState *vhost_user; } VHostUserSCSI; =20 #endif /* VHOST_USER_SCSI_H */ diff --git a/include/hw/virtio/vhost-user.h b/include/hw/virtio/vhost-user.h new file mode 100644 index 0000000000..eb8bc0d90d --- /dev/null +++ b/include/hw/virtio/vhost-user.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2017-2018 Intel Corporation + * + * This work is licensed under the terms of the GNU GPL, version 2. + * See the COPYING file in the top-level directory. + */ + +#ifndef HW_VIRTIO_VHOST_USER_H +#define HW_VIRTIO_VHOST_USER_H + +#include "chardev/char-fe.h" + +typedef struct VhostUserState { + CharBackend *chr; +} VhostUserState; + +VhostUserState *vhost_user_init(void); +void vhost_user_cleanup(VhostUserState *user); + +#endif diff --git a/net/vhost-user.c b/net/vhost-user.c index fa28aad12d..608b837175 100644 --- a/net/vhost-user.c +++ b/net/vhost-user.c @@ -12,6 +12,7 @@ #include "clients.h" #include "net/vhost_net.h" #include "net/vhost-user.h" +#include "hw/virtio/vhost-user.h" #include "chardev/char-fe.h" #include "qapi/error.h" #include "qapi/qapi-commands-net.h" @@ -23,6 +24,7 @@ typedef struct NetVhostUserState { NetClientState nc; CharBackend chr; /* only queue index 0 */ + VhostUserState *vhost_user; VHostNetState *vhost_net; guint watch; uint64_t acked_features; @@ -64,7 +66,8 @@ static void vhost_user_stop(int queues, NetClientState *n= cs[]) } } =20 -static int vhost_user_start(int queues, NetClientState *ncs[], CharBackend= *be) +static int vhost_user_start(int queues, NetClientState *ncs[], + VhostUserState *be) { VhostNetOptions options; struct vhost_net *net =3D NULL; @@ -144,7 +147,7 @@ static ssize_t vhost_user_receive(NetClientState *nc, c= onst uint8_t *buf, return size; } =20 -static void vhost_user_cleanup(NetClientState *nc) +static void net_vhost_user_cleanup(NetClientState *nc) { NetVhostUserState *s =3D DO_UPCAST(NetVhostUserState, nc, nc); =20 @@ -159,6 +162,11 @@ static void vhost_user_cleanup(NetClientState *nc) s->watch =3D 0; } qemu_chr_fe_deinit(&s->chr, true); + if (s->vhost_user) { + vhost_user_cleanup(s->vhost_user); + g_free(s->vhost_user); + s->vhost_user =3D NULL; + } } =20 qemu_purge_queued_packets(nc); @@ -182,7 +190,7 @@ static NetClientInfo net_vhost_user_info =3D { .type =3D NET_CLIENT_DRIVER_VHOST_USER, .size =3D sizeof(NetVhostUserState), .receive =3D vhost_user_receive, - .cleanup =3D vhost_user_cleanup, + .cleanup =3D net_vhost_user_cleanup, .has_vnet_hdr =3D vhost_user_has_vnet_hdr, .has_ufo =3D vhost_user_has_ufo, }; @@ -244,7 +252,7 @@ static void net_vhost_user_event(void *opaque, int even= t) trace_vhost_user_event(chr->label, event); switch (event) { case CHR_EVENT_OPENED: - if (vhost_user_start(queues, ncs, &s->chr) < 0) { + if (vhost_user_start(queues, ncs, s->vhost_user) < 0) { qemu_chr_fe_disconnect(&s->chr); return; } @@ -283,12 +291,19 @@ static int net_vhost_user_init(NetClientState *peer, = const char *device, { Error *err =3D NULL; NetClientState *nc, *nc0 =3D NULL; - NetVhostUserState *s; + VhostUserState *user =3D NULL; + NetVhostUserState *s =3D NULL; int i; =20 assert(name); assert(queues > 0); =20 + user =3D vhost_user_init(); + if (!user) { + error_report("failed to init vhost_user"); + goto err; + } + for (i =3D 0; i < queues; i++) { nc =3D qemu_new_net_client(&net_vhost_user_info, peer, device, nam= e); snprintf(nc->info_str, sizeof(nc->info_str), "vhost-user%d to %s", @@ -299,17 +314,19 @@ static int net_vhost_user_init(NetClientState *peer, = const char *device, s =3D DO_UPCAST(NetVhostUserState, nc, nc); if (!qemu_chr_fe_init(&s->chr, chr, &err)) { error_report_err(err); - return -1; + goto err; } + user->chr =3D &s->chr; } - + s =3D DO_UPCAST(NetVhostUserState, nc, nc); + s->vhost_user =3D user; } =20 s =3D DO_UPCAST(NetVhostUserState, nc, nc0); do { if (qemu_chr_fe_wait_connected(&s->chr, &err) < 0) { error_report_err(err); - return -1; + goto err; } qemu_chr_fe_set_handlers(&s->chr, NULL, NULL, net_vhost_user_event, NULL, nc0->name, NU= LL, @@ -319,6 +336,17 @@ static int net_vhost_user_init(NetClientState *peer, c= onst char *device, assert(s->vhost_net); =20 return 0; + +err: + if (user) { + vhost_user_cleanup(user); + g_free(user); + if (s) { + s->vhost_user =3D NULL; + } + } + + return -1; } =20 static Chardev *net_vhost_claim_chardev( --=20 2.17.0