[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v4 20/29] hostmem: allow preallocation of any memory
From: |
Hu Tao |
Subject: |
[Qemu-devel] [PATCH v4 20/29] hostmem: allow preallocation of any memory region |
Date: |
Mon, 9 Jun 2014 18:25:25 +0800 |
From: Paolo Bonzini <address@hidden>
And allow preallocation of file-based memory even without -mem-prealloc.
Some care is necessary because -mem-prealloc does not allow disabling
preallocation for hostmem-file.
Signed-off-by: Paolo Bonzini <address@hidden>
Signed-off-by: Hu Tao <address@hidden>
---
backends/hostmem-file.c | 3 +++
backends/hostmem.c | 42 ++++++++++++++++++++++++++++++++++++++++++
exec.c | 7 +++++++
include/exec/memory.h | 10 ++++++++++
include/exec/ram_addr.h | 1 +
include/sysemu/hostmem.h | 1 +
memory.c | 11 +++++++++++
7 files changed, 75 insertions(+)
diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
index b8df933..d3a7ef3 100644
--- a/backends/hostmem-file.c
+++ b/backends/hostmem-file.c
@@ -9,7 +9,9 @@
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
+#include "qemu-common.h"
#include "sysemu/hostmem.h"
+#include "sysemu/sysemu.h"
#include "qom/object_interfaces.h"
/* hostmem-file.c */
@@ -46,6 +48,7 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error
**errp)
error_setg(errp, "-mem-path not supported on this host");
#else
if (!memory_region_size(&backend->mr)) {
+ backend->force_prealloc = mem_prealloc;
memory_region_init_ram_from_file(&backend->mr, OBJECT(backend),
object_get_canonical_path(OBJECT(backend)),
backend->size,
diff --git a/backends/hostmem.c b/backends/hostmem.c
index fa306b4..e437275 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -105,6 +105,41 @@ static void host_memory_backend_set_dump(Object *obj, bool
value, Error **errp)
}
}
+static bool host_memory_backend_get_prealloc(Object *obj, Error **errp)
+{
+ HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+
+ return backend->prealloc || backend->force_prealloc;
+}
+
+static void host_memory_backend_set_prealloc(Object *obj, bool value,
+ Error **errp)
+{
+ HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+
+ if (backend->force_prealloc) {
+ if (value) {
+ error_setg(errp,
+ "remove -mem-prealloc to use the prealloc property");
+ return;
+ }
+ }
+
+ if (!memory_region_size(&backend->mr)) {
+ backend->prealloc = value;
+ return;
+ }
+
+ 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);
+
+ os_mem_prealloc(fd, ptr, sz);
+ backend->prealloc = true;
+ }
+}
+
static void host_memory_backend_init(Object *obj)
{
HostMemoryBackend *backend = MEMORY_BACKEND(obj);
@@ -113,6 +148,7 @@ static void host_memory_backend_init(Object *obj)
"mem-merge", true);
backend->dump = qemu_opt_get_bool(qemu_get_machine_opts(),
"dump-guest-core", true);
+ backend->prealloc = mem_prealloc;
object_property_add_bool(obj, "merge",
host_memory_backend_get_merge,
@@ -120,6 +156,9 @@ static void host_memory_backend_init(Object *obj)
object_property_add_bool(obj, "dump",
host_memory_backend_get_dump,
host_memory_backend_set_dump, NULL);
+ object_property_add_bool(obj, "prealloc",
+ host_memory_backend_get_prealloc,
+ host_memory_backend_set_prealloc, NULL);
object_property_add(obj, "size", "int",
host_memory_backend_get_size,
host_memory_backend_set_size, NULL, NULL, NULL);
@@ -165,6 +204,9 @@ host_memory_backend_memory_complete(UserCreatable *uc,
Error **errp)
if (!backend->dump) {
qemu_madvise(ptr, sz, QEMU_MADV_DONTDUMP);
}
+ if (backend->prealloc) {
+ os_mem_prealloc(memory_region_get_fd(&backend->mr), ptr, sz);
+ }
}
}
diff --git a/exec.c b/exec.c
index 739f0cf..520d673 100644
--- a/exec.c
+++ b/exec.c
@@ -1432,6 +1432,13 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
}
#endif /* !_WIN32 */
+int qemu_get_ram_fd(ram_addr_t addr)
+{
+ RAMBlock *block = qemu_get_ram_block(addr);
+
+ return block->fd;
+}
+
/* Return a host pointer to ram allocated with qemu_ram_alloc.
With the exception of the softmmu code in this file, this should
only be used for local memory (e.g. video ram) that the device owns,
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 82d7781..36226f7 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -534,6 +534,16 @@ bool memory_region_is_logging(MemoryRegion *mr);
bool memory_region_is_rom(MemoryRegion *mr);
/**
+ * memory_region_get_fd: Get a file descriptor backing a RAM memory region.
+ *
+ * Returns a file descriptor backing a file-based RAM memory region,
+ * or -1 if the region is not a file-based RAM memory region.
+ *
+ * @mr: the RAM or alias memory region being queried.
+ */
+int memory_region_get_fd(MemoryRegion *mr);
+
+/**
* memory_region_get_ram_ptr: Get a pointer into a RAM memory region.
*
* Returns a host pointer to a RAM memory region (created with
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index f9518a6..d352f60 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -27,6 +27,7 @@ ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size,
MemoryRegion *mr,
ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
MemoryRegion *mr);
ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr);
+int qemu_get_ram_fd(ram_addr_t addr);
void *qemu_get_ram_ptr(ram_addr_t addr);
void qemu_ram_free(ram_addr_t addr);
void qemu_ram_free_from_ptr(ram_addr_t addr);
diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h
index ede5ec9..4cae673 100644
--- a/include/sysemu/hostmem.h
+++ b/include/sysemu/hostmem.h
@@ -53,6 +53,7 @@ struct HostMemoryBackend {
/* protected */
uint64_t size;
bool merge, dump;
+ bool prealloc, force_prealloc;
MemoryRegion mr;
};
diff --git a/memory.c b/memory.c
index 310729a..bcef72b 100644
--- a/memory.c
+++ b/memory.c
@@ -1258,6 +1258,17 @@ void memory_region_reset_dirty(MemoryRegion *mr, hwaddr
addr,
cpu_physical_memory_reset_dirty(mr->ram_addr + addr, size, client);
}
+int memory_region_get_fd(MemoryRegion *mr)
+{
+ if (mr->alias) {
+ return memory_region_get_fd(mr->alias);
+ }
+
+ assert(mr->terminates);
+
+ return qemu_get_ram_fd(mr->ram_addr & TARGET_PAGE_MASK);
+}
+
void *memory_region_get_ram_ptr(MemoryRegion *mr)
{
if (mr->alias) {
--
1.9.3
- Re: [Qemu-devel] [PATCH v4 18/29] hostmem: add file-based HostMemoryBackend, (continued)
- Re: [Qemu-devel] [PATCH v4 18/29] hostmem: add file-based HostMemoryBackend, Igor Mammedov, 2014/06/09
- Re: [Qemu-devel] [PATCH v4 18/29] hostmem: add file-based HostMemoryBackend, Hu Tao, 2014/06/09
- Re: [Qemu-devel] [PATCH v4 18/29] hostmem: add file-based HostMemoryBackend, Paolo Bonzini, 2014/06/10
- Re: [Qemu-devel] [PATCH v4 18/29] hostmem: add file-based HostMemoryBackend, Hu Tao, 2014/06/10
- Re: [Qemu-devel] [PATCH v4 18/29] hostmem: add file-based HostMemoryBackend, Paolo Bonzini, 2014/06/10
- Re: [Qemu-devel] [PATCH v4 18/29] hostmem: add file-based HostMemoryBackend, Hu Tao, 2014/06/10
- Re: [Qemu-devel] [PATCH v4 18/29] hostmem: add file-based HostMemoryBackend, Michael S. Tsirkin, 2014/06/10
- Re: [Qemu-devel] [PATCH v4 18/29] hostmem: add file-based HostMemoryBackend, Igor Mammedov, 2014/06/10
- Re: [Qemu-devel] [PATCH v4 18/29] hostmem: add file-based HostMemoryBackend, Michael S. Tsirkin, 2014/06/10
[Qemu-devel] [PATCH v4 19/29] hostmem: add merge and dump properties, Hu Tao, 2014/06/09
[Qemu-devel] [PATCH v4 20/29] hostmem: allow preallocation of any memory region,
Hu Tao <=
[Qemu-devel] [PATCH v4 21/29] hostmem: add property to map memory with MAP_SHARED, Hu Tao, 2014/06/09
[Qemu-devel] [PATCH v4 22/29] configure: add Linux libnuma detection, Hu Tao, 2014/06/09
[Qemu-devel] [PATCH v4 23/29] hostmem: add properties for NUMA memory policy, Hu Tao, 2014/06/09
[Qemu-devel] [PATCH v4 24/29] Introduce signed range., Hu Tao, 2014/06/09