From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35104) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZoqcK-0005NY-JM for qemu-devel@nongnu.org; Wed, 21 Oct 2015 06:27:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZoqcJ-0006Gm-Bc for qemu-devel@nongnu.org; Wed, 21 Oct 2015 06:27:36 -0400 Received: from mx1.redhat.com ([209.132.183.28]:54606) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZoqcJ-0006Gi-1z for qemu-devel@nongnu.org; Wed, 21 Oct 2015 06:27:35 -0400 Date: Wed, 21 Oct 2015 13:27:31 +0300 From: "Michael S. Tsirkin" Message-ID: <1445423133-5119-19-git-send-email-mst@redhat.com> References: <1445423133-5119-1-git-send-email-mst@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline In-Reply-To: <1445423133-5119-1-git-send-email-mst@redhat.com> Content-Transfer-Encoding: quoted-printable Subject: [Qemu-devel] [PULL 18/38] vhost: alloc shareable log List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Peter Maydell , Thibaut Collet , =?us-ascii?B?PT9VVEYtOD9xP01hcmMtQW5kcj1DMz1BOT0yMEx1cmVhdT89?= From: Marc-Andr=E9 Lureau If the backend is requires it, allocate shareable memory. vhost_log_get() now uses 2 globals "vhost_log" and "vhost_log_shm", that way there is a common non-shareable log and a common shareable one. Signed-off-by: Marc-Andr=E9 Lureau Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Tested-by: Thibaut Collet --- include/hw/virtio/vhost.h | 3 ++- hw/virtio/vhost.c | 57 ++++++++++++++++++++++++++++++++++++++---= ------ 2 files changed, 49 insertions(+), 11 deletions(-) diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h index 080831e..6bf759f 100644 --- a/include/hw/virtio/vhost.h +++ b/include/hw/virtio/vhost.h @@ -31,7 +31,8 @@ typedef unsigned long vhost_log_chunk_t; struct vhost_log { unsigned long long size; int refcnt; - vhost_log_chunk_t log[0]; + int fd; + vhost_log_chunk_t *log; }; =20 struct vhost_memory; diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index f2b31b7..aec92d4 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -18,6 +18,7 @@ #include "qemu/atomic.h" #include "qemu/range.h" #include "qemu/error-report.h" +#include "qemu/memfd.h" #include #include "exec/address-spaces.h" #include "hw/virtio/virtio-bus.h" @@ -25,6 +26,7 @@ #include "migration/migration.h" =20 static struct vhost_log *vhost_log; +static struct vhost_log *vhost_log_shm; =20 static unsigned int used_memslots; static QLIST_HEAD(, vhost_dev) vhost_devices =3D @@ -302,25 +304,46 @@ static uint64_t vhost_get_log_size(struct vhost_dev= *dev) } return log_size; } -static struct vhost_log *vhost_log_alloc(uint64_t size) + +static struct vhost_log *vhost_log_alloc(uint64_t size, bool share) { - struct vhost_log *log =3D g_malloc0(sizeof *log + size * sizeof(*(lo= g->log))); + struct vhost_log *log; + uint64_t logsize =3D size * sizeof(*(log->log)); + int fd =3D -1; + + log =3D g_new0(struct vhost_log, 1); + if (share) { + log->log =3D qemu_memfd_alloc("vhost-log", logsize, + F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL= _SEAL, + &fd); + memset(log->log, 0, logsize); + } else { + log->log =3D g_malloc0(logsize); + } =20 log->size =3D size; log->refcnt =3D 1; + log->fd =3D fd; =20 return log; } =20 -static struct vhost_log *vhost_log_get(uint64_t size) +static struct vhost_log *vhost_log_get(uint64_t size, bool share) { - if (!vhost_log || vhost_log->size !=3D size) { - vhost_log =3D vhost_log_alloc(size); + struct vhost_log *log =3D share ? vhost_log_shm : vhost_log; + + if (!log || log->size !=3D size) { + log =3D vhost_log_alloc(size, share); + if (share) { + vhost_log_shm =3D log; + } else { + vhost_log =3D log; + } } else { - ++vhost_log->refcnt; + ++log->refcnt; } =20 - return vhost_log; + return log; } =20 static void vhost_log_put(struct vhost_dev *dev, bool sync) @@ -337,16 +360,29 @@ static void vhost_log_put(struct vhost_dev *dev, bo= ol sync) if (dev->log_size && sync) { vhost_log_sync_range(dev, 0, dev->log_size * VHOST_LOG_CHUNK= - 1); } + if (vhost_log =3D=3D log) { + g_free(log->log); vhost_log =3D NULL; + } else if (vhost_log_shm =3D=3D log) { + qemu_memfd_free(log->log, log->size * sizeof(*(log->log)), + log->fd); + vhost_log_shm =3D NULL; } + g_free(log); } } =20 -static inline void vhost_dev_log_resize(struct vhost_dev* dev, uint64_t = size) +static bool vhost_dev_log_is_shared(struct vhost_dev *dev) +{ + return dev->vhost_ops->vhost_requires_shm_log && + dev->vhost_ops->vhost_requires_shm_log(dev); +} + +static inline void vhost_dev_log_resize(struct vhost_dev *dev, uint64_t = size) { - struct vhost_log *log =3D vhost_log_get(size); + struct vhost_log *log =3D vhost_log_get(size, vhost_dev_log_is_share= d(dev)); uint64_t log_base =3D (uintptr_t)log->log; int r; =20 @@ -1165,7 +1201,8 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIOD= evice *vdev) uint64_t log_base; =20 hdev->log_size =3D vhost_get_log_size(hdev); - hdev->log =3D vhost_log_get(hdev->log_size); + 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_bas= e : 0); --=20 MST