[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 12/16] hostmem: Introduce "managed-size" for memory-backend-ra
From: |
David Hildenbrand |
Subject: |
[PATCH v2 12/16] hostmem: Introduce "managed-size" for memory-backend-ram |
Date: |
Wed, 12 Feb 2020 14:35:57 +0100 |
virtio-mem wants to make use of resizable memory regions. Allow to
create them by the user by specifying "managed-size".
Disallow setting "managed-size" with "prealloc" and "shared". The latter
might theoretically be possible, however has to be wired up internally
first.
Support for memory-backend-ram only for now. Support for other backends
(especially, hugepages), can be added later (and once e.g., virtio-mem
also supports hugepages).
When the memory region gets resized, apply the same settings just as when
allocating the memory.
Fence off the all such memory backends in all existing users. We'll
convert virtio-mem soon.
Signed-off-by: David Hildenbrand <address@hidden>
---
backends/hostmem-ram.c | 18 ++++++++--
backends/hostmem.c | 72 ++++++++++++++++++++++++++++++++++++++--
hw/mem/pc-dimm.c | 3 +-
hw/misc/ivshmem.c | 2 +-
hw/virtio/virtio-mem.c | 2 +-
hw/virtio/virtio-pmem.c | 2 +-
include/sysemu/hostmem.h | 8 +++--
7 files changed, 97 insertions(+), 10 deletions(-)
diff --git a/backends/hostmem-ram.c b/backends/hostmem-ram.c
index 6aab8d3a73..881276cf6b 100644
--- a/backends/hostmem-ram.c
+++ b/backends/hostmem-ram.c
@@ -29,8 +29,21 @@ ram_backend_memory_alloc(HostMemoryBackend *backend, Error
**errp)
}
name = host_memory_backend_get_name(backend);
- memory_region_init_ram_shared_nomigrate(&backend->mr, OBJECT(backend),
name,
- backend->size, backend->share, errp);
+ if (backend->managed_size) {
+ /*
+ * The size of a memory region must always be > 0 - start with 1. The
+ * managing object/device will resize accordingly.
+ */
+ g_assert(!backend->share);
+ memory_region_init_resizeable_ram(&backend->mr, OBJECT(backend), name,
+ 1, backend->size,
+ host_memory_backend_resized,
+ errp);
+ } else {
+ memory_region_init_ram_shared_nomigrate(&backend->mr, OBJECT(backend),
+ name, backend->size,
+ backend->share, errp);
+ }
g_free(name);
}
@@ -40,6 +53,7 @@ ram_backend_class_init(ObjectClass *oc, void *data)
HostMemoryBackendClass *bc = MEMORY_BACKEND_CLASS(oc);
bc->alloc = ram_backend_memory_alloc;
+ bc->managed_size_supported = true;
}
static const TypeInfo ram_backend_info = {
diff --git a/backends/hostmem.c b/backends/hostmem.c
index de37f1bf5d..c3c453753a 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -238,7 +238,10 @@ static void host_memory_backend_set_prealloc(Object *obj,
bool value,
return;
}
- if (value && !backend->prealloc) {
+ if (value && backend->managed_size) {
+ error_setg(errp, "'prealloc' is not compatible with 'managed-size'");
+ return;
+ } else if (value && !backend->prealloc) {
int fd = memory_region_get_fd(&backend->mr);
void *ptr = memory_region_get_ram_ptr(&backend->mr);
uint64_t sz = memory_region_size(&backend->mr);
@@ -292,7 +295,8 @@ bool host_memory_backend_is_mapped(HostMemoryBackend
*backend)
}
void host_memory_backend_validate(HostMemoryBackend *backend,
- const char *property, Error **errp)
+ const char *property,
+ bool managed_size_support, Error **errp)
{
char *path = object_get_canonical_path_component(OBJECT(backend));
@@ -301,6 +305,10 @@ void host_memory_backend_validate(HostMemoryBackend
*backend,
} else if (host_memory_backend_is_mapped(backend)) {
error_setg(errp, "'%s' property specifies a busy memdev: %s",
property, path);
+ } else if (backend->managed_size && !managed_size_support) {
+ error_setg(errp,
+ "'%s' property does not support a memdev with a managed
size: %s",
+ property, path);
}
g_free(path);
}
@@ -395,6 +403,24 @@ static void
host_memory_backend_apply_settings(HostMemoryBackend *backend,
}
}
+void host_memory_backend_resized(Object *owner, const char *idstr,
+ uint64_t size, void *host)
+{
+ HostMemoryBackend *backend = MEMORY_BACKEND(owner);
+ Error *local_err = NULL;
+
+ /*
+ * Just apply the settings for all (resized) memory again. Note that
+ * "shared" and "prealloc" is currently not compatible with resizable
memory
+ * regions ("managed-size"). Warn only.
+ */
+ host_memory_backend_apply_settings(backend, &local_err);
+ if (local_err) {
+ warn_report_err(local_err);
+ local_err = NULL;
+ }
+}
+
static void
host_memory_backend_memory_complete(UserCreatable *uc, Error **errp)
{
@@ -441,6 +467,9 @@ static void host_memory_backend_set_share(Object *o, bool
value, Error **errp)
if (host_memory_backend_mr_inited(backend)) {
error_setg(errp, "cannot change property value");
return;
+ } else if (value && backend->managed_size) {
+ error_setg(errp, "'prealloc' is not compatible with 'managed-size'");
+ return;
}
backend->share = value;
}
@@ -462,6 +491,39 @@ host_memory_backend_set_use_canonical_path(Object *obj,
bool value,
backend->use_canonical_path = value;
}
+static bool
+ram_backend_get_managed_size(Object *obj, Error **errp)
+{
+ return MEMORY_BACKEND(obj)->managed_size;
+}
+
+static void
+ram_backend_set_managed_size(Object *obj, bool value, Error **errp)
+{
+ HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+ HostMemoryBackendClass *bc = MEMORY_BACKEND_GET_CLASS(obj);
+
+ if (host_memory_backend_mr_inited(backend)) {
+ error_setg(errp, "cannot change property @managed_size'");
+ return;
+ } else if (value && !bc->managed_size_supported) {
+ error_setg(errp,
+ "'managed-size' is not supported yet for %s",
+ object_get_typename(obj));
+ return;
+ } else if (value && (backend->force_prealloc || backend->prealloc)) {
+ error_setg(errp,
+ "'managed-size' is not compatible with preallocated
memory");
+ return;
+ } else if (value && backend->share) {
+ error_setg(errp,
+ "'managed-size' is not compatible with shared memory");
+ return;
+ }
+
+ backend->managed_size = value;
+}
+
static void
host_memory_backend_class_init(ObjectClass *oc, void *data)
{
@@ -511,6 +573,12 @@ host_memory_backend_class_init(ObjectClass *oc, void *data)
object_class_property_add_bool(oc, "x-use-canonical-path-for-ramblock-id",
host_memory_backend_get_use_canonical_path,
host_memory_backend_set_use_canonical_path, &error_abort);
+ object_class_property_add_bool(oc, "managed-size",
+ ram_backend_get_managed_size,
+ ram_backend_set_managed_size, &error_abort);
+ object_class_property_set_description(oc, "managed-size",
+ "The owner manages the actual size, 'size' is an upper limit",
+ &error_abort);
}
static const TypeInfo host_memory_backend_info = {
diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c
index 9ee634ee89..5021cb347d 100644
--- a/hw/mem/pc-dimm.c
+++ b/hw/mem/pc-dimm.c
@@ -176,7 +176,8 @@ static void pc_dimm_realize(DeviceState *dev, Error **errp)
int nb_numa_nodes = ms->numa_state->num_nodes;
Error *err = NULL;
- host_memory_backend_validate(dimm->hostmem, PC_DIMM_MEMDEV_PROP, &err);
+ host_memory_backend_validate(dimm->hostmem, PC_DIMM_MEMDEV_PROP, false,
+ &err);
if (err) {
error_propagate(errp, err);
return;
diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index 39bffceadf..69d16c2dca 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -1037,7 +1037,7 @@ static void ivshmem_plain_realize(PCIDevice *dev, Error
**errp)
IVShmemState *s = IVSHMEM_COMMON(dev);
Error *err = NULL;
- host_memory_backend_validate(s->hostmem, "memdev", &err);
+ host_memory_backend_validate(s->hostmem, "memdev", false, &err);
if (err) {
error_propagate(errp, err);
return;
diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
index 4b7b4cf950..093b6eb0bb 100644
--- a/hw/virtio/virtio-mem.c
+++ b/hw/virtio/virtio-mem.c
@@ -415,7 +415,7 @@ static void virtio_mem_device_realize(DeviceState *dev,
Error **errp)
/* verify the memdev */
host_memory_backend_validate(vm->memdev, VIRTIO_MEM_MEMDEV_PROP,
- &local_err);
+ false, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
diff --git a/hw/virtio/virtio-pmem.c b/hw/virtio/virtio-pmem.c
index 85cb337ed5..51f01e52fd 100644
--- a/hw/virtio/virtio-pmem.c
+++ b/hw/virtio/virtio-pmem.c
@@ -107,7 +107,7 @@ static void virtio_pmem_realize(DeviceState *dev, Error
**errp)
VirtIOPMEM *pmem = VIRTIO_PMEM(dev);
Error *err = NULL;
- host_memory_backend_validate(pmem->memdev, "memdev", &err);
+ host_memory_backend_validate(pmem->memdev, "memdev", false, &err);
if (err) {
error_propagate(errp, err);
return;
diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h
index d4dbf108ca..f5ef7016bc 100644
--- a/include/sysemu/hostmem.h
+++ b/include/sysemu/hostmem.h
@@ -37,6 +37,7 @@ struct HostMemoryBackendClass {
ObjectClass parent_class;
void (*alloc)(HostMemoryBackend *backend, Error **errp);
+ bool managed_size_supported;
};
/**
@@ -53,7 +54,7 @@ struct HostMemoryBackend {
/* protected */
uint64_t size;
bool merge, dump, use_canonical_path;
- bool prealloc, force_prealloc, is_mapped, share;
+ bool prealloc, force_prealloc, is_mapped, share, managed_size;
DECLARE_BITMAP(host_nodes, MAX_NODES + 1);
HostMemPolicy policy;
@@ -61,12 +62,15 @@ struct HostMemoryBackend {
};
bool host_memory_backend_mr_inited(HostMemoryBackend *backend);
+void host_memory_backend_resized(Object *owner, const char *idstr,
+ uint64_t size, void *host);
MemoryRegion *host_memory_backend_get_memory(HostMemoryBackend *backend);
void host_memory_backend_set_mapped(HostMemoryBackend *backend, bool mapped);
bool host_memory_backend_is_mapped(HostMemoryBackend *backend);
void host_memory_backend_validate(HostMemoryBackend *backend,
- const char *property, Error **errp);
+ const char *property,
+ bool managed_size_support, Error **errp);
size_t host_memory_backend_pagesize(HostMemoryBackend *memdev);
char *host_memory_backend_get_name(HostMemoryBackend *backend);
--
2.24.1
- Re: [PATCH v2 01/16] virtio-mem: Prototype, (continued)
- [PATCH v2 03/16] hmp: Handle virtio-mem when printing memory device infos, David Hildenbrand, 2020/02/12
- [PATCH v2 04/16] numa: Handle virtio-mem in NUMA stats, David Hildenbrand, 2020/02/12
- [PATCH v2 05/16] pc: Support for virtio-mem-pci, David Hildenbrand, 2020/02/12
- [PATCH v2 06/16] exec: Provide owner when resizing memory region, David Hildenbrand, 2020/02/12
- [PATCH v2 07/16] memory: Add memory_region_max_size() and memory_region_is_resizable(), David Hildenbrand, 2020/02/12
- [PATCH v2 08/16] memory: Disallow resizing to 0, David Hildenbrand, 2020/02/12
- [PATCH v2 09/16] memory-device: properly deal with resizable memory regions, David Hildenbrand, 2020/02/12
- [PATCH v2 10/16] hostmem: Factor out applying settings, David Hildenbrand, 2020/02/12
- [PATCH v2 11/16] hostmem: Factor out common checks into host_memory_backend_validate(), David Hildenbrand, 2020/02/12
- [PATCH v2 12/16] hostmem: Introduce "managed-size" for memory-backend-ram,
David Hildenbrand <=
- [PATCH v2 13/16] qmp/hmp: Expose "managed-size" for memory backends, David Hildenbrand, 2020/02/12
- [PATCH v2 14/16] virtio-mem: Support for resizable memory regions, David Hildenbrand, 2020/02/12
- [PATCH v2 15/16] memory: Add region_resize() callback to memory notifier, David Hildenbrand, 2020/02/12
- [PATCH v2 16/16] kvm: Implement region_resize() for atomic memory section resizes, David Hildenbrand, 2020/02/12
- Re: [PATCH v2 00/16] Ram blocks with resizable anonymous allocations under POSIX, David Hildenbrand, 2020/02/12