From nobody Sat Nov 1 07:32:42 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 1527158288930272.2692632586295; Thu, 24 May 2018 03:38:08 -0700 (PDT) Received: from localhost ([::1]:37686 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fLndI-0006iQ-1T for importer@patchew.org; Thu, 24 May 2018 06:38:08 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38388) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fLnYl-0003Sa-Tw for qemu-devel@nongnu.org; Thu, 24 May 2018 06:33:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fLnYj-00053O-9F for qemu-devel@nongnu.org; Thu, 24 May 2018 06:33:27 -0400 Received: from mga17.intel.com ([192.55.52.151]:6492) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fLnYj-00052U-0P for qemu-devel@nongnu.org; Thu, 24 May 2018 06:33:25 -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:23 -0700 Received: from debian.sh.intel.com ([10.67.104.203]) by orsmga002.jf.intel.com with ESMTP; 24 May 2018 03:33:22 -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="61316247" 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:31 +0800 Message-Id: <20180524103336.21233-2-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 1/6] vhost: allow backends to filter memory sections 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" This patch introduces a vhost op for vhost backends to allow them to filter the memory sections that they can handle. Signed-off-by: Tiwei Bie --- hw/virtio/vhost-user.c | 11 +++++++++++ hw/virtio/vhost.c | 9 +++++++-- include/hw/virtio/vhost-backend.h | 4 ++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c index ca554d4ff1..da0756effe 100644 --- a/hw/virtio/vhost-user.c +++ b/hw/virtio/vhost-user.c @@ -1620,6 +1620,16 @@ vhost_user_crypto_close_session(struct vhost_dev *de= v, uint64_t session_id) return 0; } =20 +static bool vhost_user_mem_section_filter(struct vhost_dev *dev, + MemoryRegionSection *section) +{ + bool result; + + result =3D memory_region_get_fd(section->mr) >=3D 0; + + return result; +} + const VhostOps user_ops =3D { .backend_type =3D VHOST_BACKEND_TYPE_USER, .vhost_backend_init =3D vhost_user_init, @@ -1650,4 +1660,5 @@ const VhostOps user_ops =3D { .vhost_set_config =3D vhost_user_set_config, .vhost_crypto_create_session =3D vhost_user_crypto_create_session, .vhost_crypto_close_session =3D vhost_user_crypto_close_session, + .vhost_backend_mem_section_filter =3D vhost_user_mem_section_filte= r, }; diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index b08290036d..624ade9682 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -386,7 +386,7 @@ static int vhost_verify_ring_mappings(struct vhost_dev = *dev, return r; } =20 -static bool vhost_section(MemoryRegionSection *section) +static bool vhost_section(struct vhost_dev *dev, MemoryRegionSection *sect= ion) { bool result; bool log_dirty =3D memory_region_get_dirty_log_mask(section->mr) & @@ -399,6 +399,11 @@ static bool vhost_section(MemoryRegionSection *section) */ result &=3D !log_dirty; =20 + if (result && dev->vhost_ops->vhost_backend_mem_section_filter) { + result &=3D + dev->vhost_ops->vhost_backend_mem_section_filter(dev, section); + } + trace_vhost_section(section->mr->name, result); return result; } @@ -632,7 +637,7 @@ static void vhost_region_addnop(MemoryListener *listene= r, struct vhost_dev *dev =3D container_of(listener, struct vhost_dev, memory_listener); =20 - if (!vhost_section(section)) { + if (!vhost_section(dev, section)) { return; } vhost_region_add_section(dev, section); diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-ba= ckend.h index 5dac61f9ea..81283ec50f 100644 --- a/include/hw/virtio/vhost-backend.h +++ b/include/hw/virtio/vhost-backend.h @@ -101,6 +101,9 @@ typedef int (*vhost_crypto_create_session_op)(struct vh= ost_dev *dev, typedef int (*vhost_crypto_close_session_op)(struct vhost_dev *dev, uint64_t session_id); =20 +typedef bool (*vhost_backend_mem_section_filter_op)(struct vhost_dev *dev, + MemoryRegionSection *secti= on); + typedef struct VhostOps { VhostBackendType backend_type; vhost_backend_init vhost_backend_init; @@ -138,6 +141,7 @@ typedef struct VhostOps { vhost_set_config_op vhost_set_config; vhost_crypto_create_session_op vhost_crypto_create_session; vhost_crypto_close_session_op vhost_crypto_close_session; + vhost_backend_mem_section_filter_op vhost_backend_mem_section_filter; } VhostOps; =20 extern const VhostOps user_ops; --=20 2.17.0 From nobody Sat Nov 1 07:32:42 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 1527158287920905.2072748051625; Thu, 24 May 2018 03:38:07 -0700 (PDT) Received: from localhost ([::1]:37685 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fLndH-0006hm-17 for importer@patchew.org; Thu, 24 May 2018 06:38:07 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38389) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fLnYl-0003Sb-US 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 1fLnYj-00053a-Oy for qemu-devel@nongnu.org; Thu, 24 May 2018 06:33:27 -0400 Received: from mga17.intel.com ([192.55.52.151]:6492) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fLnYj-00052U-Fy for qemu-devel@nongnu.org; Thu, 24 May 2018 06:33:25 -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:24 -0700 Received: from debian.sh.intel.com ([10.67.104.203]) by orsmga002.jf.intel.com with ESMTP; 24 May 2018 03:33:23 -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="61316254" 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:32 +0800 Message-Id: <20180524103336.21233-3-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 2/6] vhost-user: allow slave to send fds via slave channel 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" Introduce VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD protocol feature to allow slave to send at most 8 descriptors in each message to master via ancillary data using the slave channel. Suggested-by: Michael S. Tsirkin Signed-off-by: Tiwei Bie --- docs/interop/vhost-user.txt | 5 +++++ hw/virtio/vhost-user.c | 27 +++++++++++++++++---------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/docs/interop/vhost-user.txt b/docs/interop/vhost-user.txt index 534caab18a..682a683eb4 100644 --- a/docs/interop/vhost-user.txt +++ b/docs/interop/vhost-user.txt @@ -367,6 +367,10 @@ The fd is provided via VHOST_USER_SET_SLAVE_REQ_FD anc= illary data. A slave may then send VHOST_USER_SLAVE_* messages to the master using this fd communication channel. =20 +If VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD protocol feature is negotiated, +slave can send file descriptors (at most 8 descriptors in each message) +to master via ancillary data using this fd communication channel. + Protocol features ----------------- =20 @@ -380,6 +384,7 @@ Protocol features #define VHOST_USER_PROTOCOL_F_CRYPTO_SESSION 7 #define VHOST_USER_PROTOCOL_F_PAGEFAULT 8 #define VHOST_USER_PROTOCOL_F_CONFIG 9 +#define VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD 10 =20 Master message types -------------------- diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c index da0756effe..75a3faef2a 100644 --- a/hw/virtio/vhost-user.c +++ b/hw/virtio/vhost-user.c @@ -30,6 +30,7 @@ =20 #define VHOST_MEMORY_MAX_NREGIONS 8 #define VHOST_USER_F_PROTOCOL_FEATURES 30 +#define VHOST_USER_SLAVE_MAX_FDS 8 =20 /* * Maximum size of virtio device config space @@ -47,6 +48,7 @@ enum VhostUserProtocolFeature { VHOST_USER_PROTOCOL_F_CRYPTO_SESSION =3D 7, VHOST_USER_PROTOCOL_F_PAGEFAULT =3D 8, VHOST_USER_PROTOCOL_F_CONFIG =3D 9, + VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD =3D 10, VHOST_USER_PROTOCOL_F_MAX }; =20 @@ -854,10 +856,10 @@ static void slave_read(void *opaque) int size, ret =3D 0; struct iovec iov; struct msghdr msgh; - int fd =3D -1; + int fd[VHOST_USER_SLAVE_MAX_FDS]; char control[CMSG_SPACE(sizeof(fd))]; struct cmsghdr *cmsg; - size_t fdsize; + int i, fdsize =3D 0; =20 memset(&msgh, 0, sizeof(msgh)); msgh.msg_iov =3D &iov; @@ -865,6 +867,8 @@ static void slave_read(void *opaque) msgh.msg_control =3D control; msgh.msg_controllen =3D sizeof(control); =20 + memset(fd, -1, sizeof(fd)); + /* Read header */ iov.iov_base =3D &hdr; iov.iov_len =3D VHOST_USER_HDR_SIZE; @@ -885,7 +889,7 @@ static void slave_read(void *opaque) if (cmsg->cmsg_level =3D=3D SOL_SOCKET && cmsg->cmsg_type =3D=3D SCM_RIGHTS) { fdsize =3D cmsg->cmsg_len - CMSG_LEN(0); - memcpy(&fd, CMSG_DATA(cmsg), fdsize); + memcpy(fd, CMSG_DATA(cmsg), fdsize); break; } } @@ -913,14 +917,15 @@ static void slave_read(void *opaque) break; default: error_report("Received unexpected msg type."); - if (fd !=3D -1) { - close(fd); - } ret =3D -EINVAL; } =20 - /* Message handlers need to make sure that fd will be consumed. */ - fd =3D -1; + /* Close the remaining file descriptors. */ + for (i =3D 0; i < fdsize; i++) { + if (fd[i] !=3D -1) { + close(fd[i]); + } + } =20 /* * REPLY_ACK feature handling. Other reply types has to be managed @@ -954,8 +959,10 @@ err: qemu_set_fd_handler(u->slave_fd, NULL, NULL, NULL); close(u->slave_fd); u->slave_fd =3D -1; - if (fd !=3D -1) { - close(fd); + for (i =3D 0; i < fdsize; i++) { + if (fd[i] !=3D -1) { + close(fd[i]); + } } return; } --=20 2.17.0 From nobody Sat Nov 1 07:32:42 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 From nobody Sat Nov 1 07:32:42 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 (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1527158160291524.1588608632645; Thu, 24 May 2018 03:36:00 -0700 (PDT) Received: from localhost ([::1]:37668 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fLnb2-0004k7-Kd for importer@patchew.org; Thu, 24 May 2018 06:35:48 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38415) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fLnYn-0003Sg-Pj for qemu-devel@nongnu.org; Thu, 24 May 2018 06:33:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fLnYm-00054d-CA for qemu-devel@nongnu.org; Thu, 24 May 2018 06:33:29 -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 1fLnYm-00053t-1R for qemu-devel@nongnu.org; Thu, 24 May 2018 06:33:28 -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:27 -0700 Received: from debian.sh.intel.com ([10.67.104.203]) by orsmga002.jf.intel.com with ESMTP; 24 May 2018 03:33:26 -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="61316262" 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:34 +0800 Message-Id: <20180524103336.21233-5-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 4/6] vhost-user: support registering external host notifiers 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" This patch introduces VHOST_USER_PROTOCOL_F_HOST_NOTIFIER. With this feature negotiated, vhost-user backend can register memory region based host notifiers. And it will allow the guest driver in the VM to notify the hardware accelerator at the vhost-user backend directly. Signed-off-by: Tiwei Bie --- docs/interop/vhost-user.txt | 33 ++++++++++ hw/virtio/vhost-user.c | 113 +++++++++++++++++++++++++++++++++ include/hw/virtio/vhost-user.h | 8 +++ 3 files changed, 154 insertions(+) diff --git a/docs/interop/vhost-user.txt b/docs/interop/vhost-user.txt index 682a683eb4..d51fd58242 100644 --- a/docs/interop/vhost-user.txt +++ b/docs/interop/vhost-user.txt @@ -132,6 +132,16 @@ Depending on the request type, payload can be: Payload: Size bytes array holding the contents of the virtio device's configuration space =20 + * Vring area description + ----------------------- + | u64 | size | offset | + ----------------------- + + u64: a 64-bit integer contains vring index and flags + Size: a 64-bit size of this area + Offset: a 64-bit offset of this area from the start of the + supplied file descriptor + In QEMU the vhost-user message is implemented with the following struct: =20 typedef struct VhostUserMsg { @@ -146,6 +156,7 @@ typedef struct VhostUserMsg { VhostUserLog log; struct vhost_iotlb_msg iotlb; VhostUserConfig config; + VhostUserVringArea area; }; } QEMU_PACKED VhostUserMsg; =20 @@ -385,6 +396,7 @@ Protocol features #define VHOST_USER_PROTOCOL_F_PAGEFAULT 8 #define VHOST_USER_PROTOCOL_F_CONFIG 9 #define VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD 10 +#define VHOST_USER_PROTOCOL_F_HOST_NOTIFIER 11 =20 Master message types -------------------- @@ -782,6 +794,27 @@ Slave message types the VHOST_USER_NEED_REPLY flag, master must respond with zero when operation is successfully completed, or non-zero otherwise. =20 + * VHOST_USER_SLAVE_VRING_HOST_NOTIFIER_MSG + + Id: 3 + Equivalent ioctl: N/A + Slave payload: vring area description + Master payload: N/A + + Sets host notifier for a specified queue. The queue index is contain= ed + in the u64 field of the vring area description. The host notifier is + described by the file descriptor (typically it's a VFIO device fd) w= hich + is passed as ancillary data and the size (which is mmap size and sho= uld + be the same as host page size) and offset (which is mmap offset) car= ried + in the vring area description. QEMU can mmap the file descriptor bas= ed + on the size and offset to get a memory range. Registering a host not= ifier + means mapping this memory range to the VM as the specified queue's n= otify + MMIO region. Slave sends this request to tell QEMU to de-register the + existing notifier if any and register the new notifier if the reques= t is + sent with a file descriptor. + This request should be sent only when VHOST_USER_PROTOCOL_F_HOST_NOT= IFIER + protocol feature has been successfully negotiated. + VHOST_USER_PROTOCOL_F_REPLY_ACK: ------------------------------- The original vhost-user specification only demands replies for certain diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c index 70b9610c87..b041343632 100644 --- a/hw/virtio/vhost-user.c +++ b/hw/virtio/vhost-user.c @@ -13,6 +13,7 @@ #include "hw/virtio/vhost.h" #include "hw/virtio/vhost-user.h" #include "hw/virtio/vhost-backend.h" +#include "hw/virtio/virtio.h" #include "hw/virtio/virtio-net.h" #include "chardev/char-fe.h" #include "sysemu/kvm.h" @@ -50,6 +51,7 @@ enum VhostUserProtocolFeature { VHOST_USER_PROTOCOL_F_PAGEFAULT =3D 8, VHOST_USER_PROTOCOL_F_CONFIG =3D 9, VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD =3D 10, + VHOST_USER_PROTOCOL_F_HOST_NOTIFIER =3D 11, VHOST_USER_PROTOCOL_F_MAX }; =20 @@ -94,6 +96,7 @@ typedef enum VhostUserSlaveRequest { VHOST_USER_SLAVE_NONE =3D 0, VHOST_USER_SLAVE_IOTLB_MSG =3D 1, VHOST_USER_SLAVE_CONFIG_CHANGE_MSG =3D 2, + VHOST_USER_SLAVE_VRING_HOST_NOTIFIER_MSG =3D 3, VHOST_USER_SLAVE_MAX } VhostUserSlaveRequest; =20 @@ -138,6 +141,12 @@ static VhostUserConfig c __attribute__ ((unused)); + sizeof(c.size) \ + sizeof(c.flags)) =20 +typedef struct VhostUserVringArea { + uint64_t u64; + uint64_t size; + uint64_t offset; +} VhostUserVringArea; + typedef struct { VhostUserRequest request; =20 @@ -159,6 +168,7 @@ typedef union { struct vhost_iotlb_msg iotlb; VhostUserConfig config; VhostUserCryptoSession session; + VhostUserVringArea area; } VhostUserPayload; =20 typedef struct VhostUserMsg { @@ -640,9 +650,37 @@ static int vhost_user_set_vring_num(struct vhost_dev *= dev, return vhost_set_vring(dev, VHOST_USER_SET_VRING_NUM, ring); } =20 +static void vhost_user_host_notifier_restore(struct vhost_dev *dev, + int queue_idx) +{ + struct vhost_user *u =3D dev->opaque; + VhostUserHostNotifier *n =3D &u->user->notifier[queue_idx]; + VirtIODevice *vdev =3D dev->vdev; + + if (n->addr && !n->set) { + virtio_queue_set_host_notifier_mr(vdev, queue_idx, &n->mr, true); + n->set =3D true; + } +} + +static void vhost_user_host_notifier_remove(struct vhost_dev *dev, + int queue_idx) +{ + struct vhost_user *u =3D dev->opaque; + VhostUserHostNotifier *n =3D &u->user->notifier[queue_idx]; + VirtIODevice *vdev =3D dev->vdev; + + if (n->addr && n->set) { + virtio_queue_set_host_notifier_mr(vdev, queue_idx, &n->mr, false); + n->set =3D false; + } +} + static int vhost_user_set_vring_base(struct vhost_dev *dev, struct vhost_vring_state *ring) { + vhost_user_host_notifier_restore(dev, ring->index); + return vhost_set_vring(dev, VHOST_USER_SET_VRING_BASE, ring); } =20 @@ -676,6 +714,8 @@ static int vhost_user_get_vring_base(struct vhost_dev *= dev, .hdr.size =3D sizeof(msg.payload.state), }; =20 + vhost_user_host_notifier_remove(dev, ring->index); + if (vhost_user_write(dev, &msg, NULL, 0) < 0) { return -1; } @@ -849,6 +889,66 @@ static int vhost_user_slave_handle_config_change(struc= t vhost_dev *dev) return ret; } =20 +static int vhost_user_slave_handle_vring_host_notifier(struct vhost_dev *d= ev, + VhostUserVringArea = *area, + int fd) +{ + int queue_idx =3D area->u64 & VHOST_USER_VRING_IDX_MASK; + size_t page_size =3D qemu_real_host_page_size; + struct vhost_user *u =3D dev->opaque; + VhostUserState *user =3D u->user; + VirtIODevice *vdev =3D dev->vdev; + VhostUserHostNotifier *n; + void *addr; + char *name; + + if (!virtio_has_feature(dev->protocol_features, + VHOST_USER_PROTOCOL_F_HOST_NOTIFIER) || + vdev =3D=3D NULL || queue_idx >=3D virtio_get_num_queues(vdev)) { + return -1; + } + + n =3D &user->notifier[queue_idx]; + + if (n->addr) { + virtio_queue_set_host_notifier_mr(vdev, queue_idx, &n->mr, false); + object_unparent(OBJECT(&n->mr)); + munmap(n->addr, page_size); + n->addr =3D NULL; + } + + if (area->u64 & VHOST_USER_VRING_NOFD_MASK) { + return 0; + } + + /* Sanity check. */ + if (area->size !=3D page_size) { + return -1; + } + + addr =3D mmap(NULL, page_size, PROT_READ | PROT_WRITE, MAP_SHARED, + fd, area->offset); + if (addr =3D=3D MAP_FAILED) { + return -1; + } + + name =3D g_strdup_printf("vhost-user/host-notifier@%p mmaps[%d]", + user, queue_idx); + memory_region_init_ram_device_ptr(&n->mr, OBJECT(vdev), name, + page_size, addr); + g_free(name); + + if (virtio_queue_set_host_notifier_mr(vdev, queue_idx, &n->mr, true)) { + munmap(addr, page_size); + return -1; + } + + n->addr =3D addr; + n->set =3D true; + + return 0; +} + static void slave_read(void *opaque) { struct vhost_dev *dev =3D opaque; @@ -917,6 +1017,10 @@ static void slave_read(void *opaque) case VHOST_USER_SLAVE_CONFIG_CHANGE_MSG : ret =3D vhost_user_slave_handle_config_change(dev); break; + case VHOST_USER_SLAVE_VRING_HOST_NOTIFIER_MSG: + ret =3D vhost_user_slave_handle_vring_host_notifier(dev, &payload.= area, + fd[0]); + break; default: error_report("Received unexpected msg type."); ret =3D -EINVAL; @@ -1648,6 +1752,15 @@ VhostUserState *vhost_user_init(void) =20 void vhost_user_cleanup(VhostUserState *user) { + int i; + + for (i =3D 0; i < VIRTIO_QUEUE_MAX; i++) { + if (user->notifier[i].addr) { + object_unparent(OBJECT(&user->notifier[i].mr)); + munmap(user->notifier[i].addr, qemu_real_host_page_size); + user->notifier[i].addr =3D NULL; + } + } } =20 const VhostOps user_ops =3D { diff --git a/include/hw/virtio/vhost-user.h b/include/hw/virtio/vhost-user.h index eb8bc0d90d..fd660393a0 100644 --- a/include/hw/virtio/vhost-user.h +++ b/include/hw/virtio/vhost-user.h @@ -9,9 +9,17 @@ #define HW_VIRTIO_VHOST_USER_H =20 #include "chardev/char-fe.h" +#include "hw/virtio/virtio.h" + +typedef struct VhostUserHostNotifier { + MemoryRegion mr; + void *addr; + bool set; +} VhostUserHostNotifier; =20 typedef struct VhostUserState { CharBackend *chr; + VhostUserHostNotifier notifier[VIRTIO_QUEUE_MAX]; } VhostUserState; =20 VhostUserState *vhost_user_init(void); --=20 2.17.0 From nobody Sat Nov 1 07:32:42 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 1527158397046670.9674553262591; Thu, 24 May 2018 03:39:57 -0700 (PDT) Received: from localhost ([::1]:37694 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fLnf2-00080g-2U for importer@patchew.org; Thu, 24 May 2018 06:39:56 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38426) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fLnYo-0003Si-Gg for qemu-devel@nongnu.org; Thu, 24 May 2018 06:33:35 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fLnYn-00054w-CE 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 1fLnYn-00053t-07 for qemu-devel@nongnu.org; Thu, 24 May 2018 06:33:29 -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:28 -0700 Received: from debian.sh.intel.com ([10.67.104.203]) by orsmga002.jf.intel.com with ESMTP; 24 May 2018 03:33:27 -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="61316266" 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:35 +0800 Message-Id: <20180524103336.21233-6-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 5/6] libvhost-user: support host notifier 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" This patch introduces the host notifier support in libvhost-user. A new API is added to support setting host notifier for each queue. Signed-off-by: Tiwei Bie --- contrib/libvhost-user/libvhost-user.c | 81 ++++++++++++++++++++++++--- contrib/libvhost-user/libvhost-user.h | 32 +++++++++++ 2 files changed, 105 insertions(+), 8 deletions(-) diff --git a/contrib/libvhost-user/libvhost-user.c b/contrib/libvhost-user/= libvhost-user.c index 54e643d871..a6b46cdc03 100644 --- a/contrib/libvhost-user/libvhost-user.c +++ b/contrib/libvhost-user/libvhost-user.c @@ -314,11 +314,6 @@ vu_message_write(VuDev *dev, int conn_fd, VhostUserMsg= *vmsg) msg.msg_controllen =3D 0; } =20 - /* Set the version in the flags when sending the reply */ - vmsg->flags &=3D ~VHOST_USER_VERSION_MASK; - vmsg->flags |=3D VHOST_USER_VERSION; - vmsg->flags |=3D VHOST_USER_REPLY_MASK; - do { rc =3D sendmsg(conn_fd, &msg, 0); } while (rc < 0 && (errno =3D=3D EINTR || errno =3D=3D EAGAIN)); @@ -341,6 +336,39 @@ vu_message_write(VuDev *dev, int conn_fd, VhostUserMsg= *vmsg) return true; } =20 +static bool +vu_send_reply(VuDev *dev, int conn_fd, VhostUserMsg *vmsg) +{ + /* Set the version in the flags when sending the reply */ + vmsg->flags &=3D ~VHOST_USER_VERSION_MASK; + vmsg->flags |=3D VHOST_USER_VERSION; + vmsg->flags |=3D VHOST_USER_REPLY_MASK; + + return vu_message_write(dev, conn_fd, vmsg); +} + +static bool +vu_process_message_reply(VuDev *dev, const VhostUserMsg *vmsg) +{ + VhostUserMsg msg_reply; + + if ((vmsg->flags & VHOST_USER_NEED_REPLY_MASK) =3D=3D 0) { + return true; + } + + if (!vu_message_read(dev, dev->slave_fd, &msg_reply)) { + return false; + } + + if (msg_reply.request !=3D vmsg->request) { + DPRINT("Received unexpected msg type. Expected %d received %d", + vmsg->request, msg_reply.request); + return false; + } + + return msg_reply.payload.u64 =3D=3D 0; +} + /* Kick the log_call_fd if required. */ static void vu_log_kick(VuDev *dev) @@ -536,7 +564,7 @@ vu_set_mem_table_exec_postcopy(VuDev *dev, VhostUserMsg= *vmsg) =20 /* Send the message back to qemu with the addresses filled in */ vmsg->fd_num =3D 0; - if (!vu_message_write(dev, dev->sock, vmsg)) { + if (!vu_send_reply(dev, dev->sock, vmsg)) { vu_panic(dev, "failed to respond to set-mem-table for postcopy"); return false; } @@ -916,6 +944,41 @@ void vu_set_queue_handler(VuDev *dev, VuVirtq *vq, } } =20 +bool vu_set_queue_host_notifier(VuDev *dev, VuVirtq *vq, int fd, + int size, int offset) +{ + int qidx =3D vq - dev->vq; + int fd_num =3D 0; + VhostUserMsg vmsg =3D { + .request =3D VHOST_USER_SLAVE_VRING_HOST_NOTIFIER_MSG, + .flags =3D VHOST_USER_VERSION | VHOST_USER_NEED_REPLY_MASK, + .size =3D sizeof(vmsg.payload.area), + .payload.area =3D { + .u64 =3D qidx & VHOST_USER_VRING_IDX_MASK, + .size =3D size, + .offset =3D offset, + }, + }; + + if (fd =3D=3D -1) { + vmsg.payload.area.u64 |=3D VHOST_USER_VRING_NOFD_MASK; + } else { + vmsg.fds[fd_num++] =3D fd; + } + + vmsg.fd_num =3D fd_num; + + if ((dev->protocol_features & VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD) =3D= =3D 0) { + return false; + } + + if (!vu_message_write(dev, dev->slave_fd, &vmsg)) { + return false; + } + + return vu_process_message_reply(dev, &vmsg); +} + static bool vu_set_vring_call_exec(VuDev *dev, VhostUserMsg *vmsg) { @@ -968,7 +1031,9 @@ static bool vu_get_protocol_features_exec(VuDev *dev, VhostUserMsg *vmsg) { uint64_t features =3D 1ULL << VHOST_USER_PROTOCOL_F_LOG_SHMFD | - 1ULL << VHOST_USER_PROTOCOL_F_SLAVE_REQ; + 1ULL << VHOST_USER_PROTOCOL_F_SLAVE_REQ | + 1ULL << VHOST_USER_PROTOCOL_F_HOST_NOTIFIER | + 1ULL << VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD; =20 if (have_userfault()) { features |=3D 1ULL << VHOST_USER_PROTOCOL_F_PAGEFAULT; @@ -1252,7 +1317,7 @@ vu_dispatch(VuDev *dev) goto end; } =20 - if (!vu_message_write(dev, dev->sock, &vmsg)) { + if (!vu_send_reply(dev, dev->sock, &vmsg)) { goto end; } =20 diff --git a/contrib/libvhost-user/libvhost-user.h b/contrib/libvhost-user/= libvhost-user.h index b27075ea3b..4aa55b4d2d 100644 --- a/contrib/libvhost-user/libvhost-user.h +++ b/contrib/libvhost-user/libvhost-user.h @@ -51,6 +51,8 @@ enum VhostUserProtocolFeature { VHOST_USER_PROTOCOL_F_CRYPTO_SESSION =3D 7, VHOST_USER_PROTOCOL_F_PAGEFAULT =3D 8, VHOST_USER_PROTOCOL_F_CONFIG =3D 9, + VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD =3D 10, + VHOST_USER_PROTOCOL_F_HOST_NOTIFIER =3D 11, =20 VHOST_USER_PROTOCOL_F_MAX }; @@ -92,6 +94,14 @@ typedef enum VhostUserRequest { VHOST_USER_MAX } VhostUserRequest; =20 +typedef enum VhostUserSlaveRequest { + VHOST_USER_SLAVE_NONE =3D 0, + VHOST_USER_SLAVE_IOTLB_MSG =3D 1, + VHOST_USER_SLAVE_CONFIG_CHANGE_MSG =3D 2, + VHOST_USER_SLAVE_VRING_HOST_NOTIFIER_MSG =3D 3, + VHOST_USER_SLAVE_MAX +} VhostUserSlaveRequest; + typedef struct VhostUserMemoryRegion { uint64_t guest_phys_addr; uint64_t memory_size; @@ -122,6 +132,12 @@ static VhostUserConfig c __attribute__ ((unused)); + sizeof(c.size) \ + sizeof(c.flags)) =20 +typedef struct VhostUserVringArea { + uint64_t u64; + uint64_t size; + uint64_t offset; +} VhostUserVringArea; + #if defined(_WIN32) # define VU_PACKED __attribute__((gcc_struct, packed)) #else @@ -133,6 +149,7 @@ typedef struct VhostUserMsg { =20 #define VHOST_USER_VERSION_MASK (0x3) #define VHOST_USER_REPLY_MASK (0x1 << 2) +#define VHOST_USER_NEED_REPLY_MASK (0x1 << 3) uint32_t flags; uint32_t size; /* the following payload size */ =20 @@ -145,6 +162,7 @@ typedef struct VhostUserMsg { VhostUserMemory memory; VhostUserLog log; VhostUserConfig config; + VhostUserVringArea area; } payload; =20 int fds[VHOST_MEMORY_MAX_NREGIONS]; @@ -368,6 +386,20 @@ VuVirtq *vu_get_queue(VuDev *dev, int qidx); void vu_set_queue_handler(VuDev *dev, VuVirtq *vq, vu_queue_handler_cb handler); =20 +/** + * vu_set_queue_host_notifier: + * @dev: a VuDev context + * @vq: a VuVirtq queue + * @fd: a file descriptor + * @size: host page size + * @offset: notifier offset in @fd file + * + * Set queue's host notifier. This function may be called several + * times for the same queue. If called with -1 @fd, the notifier + * is removed. + */ +bool vu_set_queue_host_notifier(VuDev *dev, VuVirtq *vq, int fd, + int size, int offset); =20 /** * vu_queue_set_notification: --=20 2.17.0 From nobody Sat Nov 1 07:32:42 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 1527158396427747.958413375848; Thu, 24 May 2018 03:39:56 -0700 (PDT) Received: from localhost ([::1]:37693 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fLnf1-0007zz-1L for importer@patchew.org; Thu, 24 May 2018 06:39:55 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38456) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fLnYp-0003Sp-O2 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 1fLnYo-00055T-K0 for qemu-devel@nongnu.org; Thu, 24 May 2018 06:33:31 -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 1fLnYo-00053t-C8 for qemu-devel@nongnu.org; Thu, 24 May 2018 06:33:30 -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:29 -0700 Received: from debian.sh.intel.com ([10.67.104.203]) by orsmga002.jf.intel.com with ESMTP; 24 May 2018 03:33:28 -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="61316270" 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:36 +0800 Message-Id: <20180524103336.21233-7-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 6/6] vhost-user-bridge: support host notifier 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" This patch introduces the host notifier support in vhost-user-bridge. A new option (-H) is added to use the host notifier. This is mainly used to test the host notifier implementation in vhost user. Signed-off-by: Tiwei Bie --- tests/vhost-user-bridge.c | 98 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 95 insertions(+), 3 deletions(-) diff --git a/tests/vhost-user-bridge.c b/tests/vhost-user-bridge.c index e0605a529e..0884294141 100644 --- a/tests/vhost-user-bridge.c +++ b/tests/vhost-user-bridge.c @@ -29,6 +29,7 @@ =20 #define _FILE_OFFSET_BITS 64 =20 +#include "qemu/atomic.h" #include "qemu/osdep.h" #include "qemu/iov.h" #include "standard-headers/linux/virtio_net.h" @@ -65,6 +66,11 @@ typedef struct VubrDev { int sock; int ready; int quit; + struct { + int fd; + void *addr; + pthread_t thread; + } notifier; } VubrDev; =20 static void @@ -445,14 +451,22 @@ static uint64_t vubr_get_features(VuDev *dev) { return 1ULL << VIRTIO_NET_F_GUEST_ANNOUNCE | - 1ULL << VIRTIO_NET_F_MRG_RXBUF; + 1ULL << VIRTIO_NET_F_MRG_RXBUF | + 1ULL << VIRTIO_F_VERSION_1; } =20 static void vubr_queue_set_started(VuDev *dev, int qidx, bool started) { + VubrDev *vubr =3D container_of(dev, VubrDev, vudev); VuVirtq *vq =3D vu_get_queue(dev, qidx); =20 + if (started && vubr->notifier.fd >=3D 0) { + vu_set_queue_host_notifier(dev, vq, vubr->notifier.fd, + getpagesize(), + qidx * getpagesize()); + } + if (qidx % 2 =3D=3D 1) { vu_set_queue_handler(dev, vq, started ? vubr_handle_tx : NULL); } @@ -522,6 +536,8 @@ vubr_new(const char *path, bool client) vubr_die("socket"); } =20 + dev->notifier.fd =3D -1; + un.sun_family =3D AF_UNIX; strcpy(un.sun_path, path); len =3D sizeof(un.sun_family) + strlen(path); @@ -559,6 +575,73 @@ vubr_new(const char *path, bool client) return dev; } =20 +static void *notifier_thread(void *arg) +{ + VuDev *dev =3D (VuDev *)arg; + VubrDev *vubr =3D container_of(dev, VubrDev, vudev); + int pagesize =3D getpagesize(); + int qidx; + + while (true) { + for (qidx =3D 0; qidx < VHOST_MAX_NR_VIRTQUEUE; qidx++) { + uint16_t *n =3D vubr->notifier.addr + pagesize * qidx; + + if (*n =3D=3D qidx) { + *n =3D 0xffff; + /* We won't miss notifications if we reset + * the memory first. */ + smp_mb(); + + DPRINT("Got a notification for queue%d via host notifier.\= n", + qidx); + + if (qidx % 2 =3D=3D 1) { + vubr_handle_tx(dev, qidx); + } + } + usleep(1000); + } + } + + return NULL; +} + +static void +vubr_host_notifier_setup(VubrDev *dev) +{ + char template[] =3D "/tmp/vubr-XXXXXX"; + pthread_t thread; + size_t length; + void *addr; + int fd; + + length =3D getpagesize() * VHOST_MAX_NR_VIRTQUEUE; + + fd =3D mkstemp(template); + if (fd < 0) { + vubr_die("mkstemp()"); + } + + if (posix_fallocate(fd, 0, length) !=3D 0) { + vubr_die("posix_fallocate()"); + } + + addr =3D mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (addr =3D=3D MAP_FAILED) { + vubr_die("mmap()"); + } + + memset(addr, 0xff, length); + + if (pthread_create(&thread, NULL, notifier_thread, &dev->vudev) !=3D 0= ) { + vubr_die("pthread_create()"); + } + + dev->notifier.fd =3D fd; + dev->notifier.addr =3D addr; + dev->notifier.thread =3D thread; +} + static void vubr_set_host(struct sockaddr_in *saddr, const char *host) { @@ -673,8 +756,9 @@ main(int argc, char *argv[]) VubrDev *dev; int opt; bool client =3D false; + bool host_notifier =3D false; =20 - while ((opt =3D getopt(argc, argv, "l:r:u:c")) !=3D -1) { + while ((opt =3D getopt(argc, argv, "l:r:u:cH")) !=3D -1) { =20 switch (opt) { case 'l': @@ -693,6 +777,9 @@ main(int argc, char *argv[]) case 'c': client =3D true; break; + case 'H': + host_notifier =3D true; + break; default: goto out; } @@ -708,6 +795,10 @@ main(int argc, char *argv[]) return 1; } =20 + if (host_notifier) { + vubr_host_notifier_setup(dev); + } + vubr_backend_udp_setup(dev, lhost, lport, rhost, rport); vubr_run(dev); =20 @@ -717,7 +808,7 @@ main(int argc, char *argv[]) =20 out: fprintf(stderr, "Usage: %s ", argv[0]); - fprintf(stderr, "[-c] [-u ud_socket_path] [-l lhost:lport] [-r rhost:r= port]\n"); + fprintf(stderr, "[-c] [-H] [-u ud_socket_path] [-l lhost:lport] [-r rh= ost:rport]\n"); fprintf(stderr, "\t-u path to unix doman socket. default: %s\n", DEFAULT_UD_SOCKET); fprintf(stderr, "\t-l local host and port. default: %s:%s\n", @@ -725,6 +816,7 @@ out: fprintf(stderr, "\t-r remote host and port. default: %s:%s\n", DEFAULT_RHOST, DEFAULT_RPORT); fprintf(stderr, "\t-c client mode\n"); + fprintf(stderr, "\t-H use host notifier\n"); =20 return 1; } --=20 2.17.0