[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v6 10/24] vhost: alloc shareable log
From: |
marcandre . lureau |
Subject: |
[Qemu-devel] [PATCH v6 10/24] vhost: alloc shareable log |
Date: |
Tue, 29 Sep 2015 18:34:40 +0200 |
From: Marc-André Lureau <address@hidden>
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é Lureau <address@hidden>
---
hw/virtio/vhost.c | 57 ++++++++++++++++++++++++++++++++++++++---------
include/hw/virtio/vhost.h | 3 ++-
2 files changed, 49 insertions(+), 11 deletions(-)
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 37bf603..63fa2bf 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 <linux/vhost.h>
#include "exec/address-spaces.h"
#include "hw/virtio/virtio-bus.h"
@@ -25,6 +26,7 @@
#include "migration/migration.h"
static struct vhost_log *vhost_log;
+static struct vhost_log *vhost_log_shm;
static void vhost_dev_sync_region(struct vhost_dev *dev,
MemoryRegionSection *section,
@@ -286,25 +288,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 = g_malloc0(sizeof *log + size *
sizeof(*(log->log)));
+ struct vhost_log *log;
+ uint64_t logsize = size * sizeof(*(log->log));
+ int fd = -1;
+
+ log = g_new0(struct vhost_log, 1);
+ if (share) {
+ log->log = qemu_memfd_alloc("vhost-log", logsize,
+ F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL,
+ &fd);
+ memset(log->log, 0, logsize);
+ } else {
+ log->log = g_malloc0(logsize);
+ }
log->size = size;
log->refcnt = 1;
+ log->fd = fd;
return log;
}
-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 != size) {
- vhost_log = vhost_log_alloc(size);
+ struct vhost_log *log = share ? vhost_log_shm : vhost_log;
+
+ if (!log || log->size != size) {
+ log = vhost_log_alloc(size, share);
+ if (share) {
+ vhost_log_shm = log;
+ } else {
+ vhost_log = log;
+ }
} else {
- ++vhost_log->refcnt;
+ ++log->refcnt;
}
- return vhost_log;
+ return log;
}
static void vhost_log_put(struct vhost_dev *dev, bool sync)
@@ -321,16 +344,29 @@ static void vhost_log_put(struct vhost_dev *dev, bool
sync)
if (dev->log_size && sync) {
vhost_log_sync_range(dev, 0, dev->log_size * VHOST_LOG_CHUNK - 1);
}
+
if (vhost_log == log) {
+ g_free(log->log);
vhost_log = NULL;
+ } else if (vhost_log_shm == log) {
+ qemu_memfd_free(log->log, log->size * sizeof(*(log->log)),
+ log->fd);
+ vhost_log_shm = NULL;
}
+
g_free(log);
}
}
-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 = vhost_log_get(size);
+ struct vhost_log *log = vhost_log_get(size, vhost_dev_log_is_shared(dev));
uint64_t log_base = (uintptr_t)log->log;
int r;
@@ -1138,7 +1174,8 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice
*vdev)
uint64_t log_base;
hdev->log_size = vhost_get_log_size(hdev);
- hdev->log = vhost_log_get(hdev->log_size);
+ hdev->log = vhost_log_get(hdev->log_size,
+ vhost_dev_log_is_shared(hdev));
log_base = (uintptr_t)hdev->log->log;
r = hdev->vhost_ops->vhost_set_log_base(hdev,
hdev->log_size ? log_base : 0);
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index c3758f3..7e7dc45 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;
};
struct vhost_memory;
--
2.4.3
- Re: [Qemu-devel] [PATCH v6 04/24] util: add linux-only memfd fallback, (continued)
- [Qemu-devel] [PATCH v6 07/24] vhost: document log resizing, marcandre . lureau, 2015/10/08
- [Qemu-devel] [PATCH v6 12/24] vhost-user: add a migration blocker, marcandre . lureau, 2015/10/08
- [Qemu-devel] [PATCH v6 03/24] linux-headers: add unistd.h, marcandre . lureau, 2015/10/08
- [Qemu-devel] [PATCH v6 17/24] vhost user: add rarp sending after live migration for legacy guest, marcandre . lureau, 2015/10/08
- [Qemu-devel] [PATCH v6 20/24] vhost-user-test: wrap server in TestServer struct, marcandre . lureau, 2015/10/08
- [Qemu-devel] [PATCH v6 02/24] configure: probe for memfd, marcandre . lureau, 2015/10/08
- [Qemu-devel] [PATCH v6 05/24] util: add memfd helpers, marcandre . lureau, 2015/10/08
- [Qemu-devel] [PATCH v6 10/24] vhost: alloc shareable log,
marcandre . lureau <=
- [Qemu-devel] [PATCH v6 18/24] vhost-user-test: move wait_for_fds() out, marcandre . lureau, 2015/10/08
- [Qemu-devel] [PATCH v6 19/24] vhost-user-test: remove useless static check, marcandre . lureau, 2015/10/08
- [Qemu-devel] [PATCH v6 21/24] vhost-user-test: learn to tweak various qemu arguments, marcandre . lureau, 2015/10/08