[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 09/25] vhost: alloc shareable log
From: |
Michael S. Tsirkin |
Subject: |
[Qemu-devel] [PULL 09/25] vhost: alloc shareable log |
Date: |
Fri, 9 Oct 2015 00:17:07 +0300 |
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>
Reviewed-by: Michael S. Tsirkin <address@hidden>
Signed-off-by: Michael S. Tsirkin <address@hidden>
---
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 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;
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);
--
MST
- [Qemu-devel] [PULL 00/25] virtio,pc features, fixes, Michael S. Tsirkin, 2015/10/08
- [Qemu-devel] [PULL 01/25] configure: probe for memfd, Michael S. Tsirkin, 2015/10/08
- [Qemu-devel] [PULL 04/25] util: add memfd helpers, Michael S. Tsirkin, 2015/10/08
- [Qemu-devel] [PULL 05/25] util: add fallback for qemu_memfd_alloc(), Michael S. Tsirkin, 2015/10/08
- [Qemu-devel] [PULL 06/25] vhost: document log resizing, Michael S. Tsirkin, 2015/10/08
- [Qemu-devel] [PULL 07/25] vhost: add vhost_set_log_base op, Michael S. Tsirkin, 2015/10/08
- [Qemu-devel] [PULL 03/25] util: add linux-only memfd fallback, Michael S. Tsirkin, 2015/10/08
- [Qemu-devel] [PULL 09/25] vhost: alloc shareable log,
Michael S. Tsirkin <=
- [Qemu-devel] [PULL 10/25] vhost-user: send log shm fd along with log_base, Michael S. Tsirkin, 2015/10/08
- [Qemu-devel] [PULL 13/25] vhost-user: document migration log, Michael S. Tsirkin, 2015/10/08
- [Qemu-devel] [PULL 14/25] net: add trace_vhost_user_event, Michael S. Tsirkin, 2015/10/08
- [Qemu-devel] [PULL 15/25] vhost user: add support of live migration, Michael S. Tsirkin, 2015/10/08
- [Qemu-devel] [PULL 20/25] vhost-user-test: remove useless static check, Michael S. Tsirkin, 2015/10/08
- [Qemu-devel] [PULL 21/25] vhost-user-test: wrap server in TestServer struct, Michael S. Tsirkin, 2015/10/08
- [Qemu-devel] [PULL 24/25] vhost-user-test: check ownership during migration, Michael S. Tsirkin, 2015/10/08
- [Qemu-devel] [PULL 22/25] vhost-user-test: learn to tweak various qemu arguments, Michael S. Tsirkin, 2015/10/08
- [Qemu-devel] [PULL 25/25] intel_iommu: Add support for translation for devices behind bridges, Michael S. Tsirkin, 2015/10/08
- [Qemu-devel] [PULL 11/25] vhost-user: add a migration blocker, Michael S. Tsirkin, 2015/10/09