提交 a35ba7be 编写于 作者: P Paolo Bonzini 提交者: Michael S. Tsirkin

hostmem: allow preallocation of any memory region

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: NPaolo Bonzini <pbonzini@redhat.com>
Signed-off-by: NHu Tao <hutao@cn.fujitsu.com>
Acked-by: NMichael S. Tsirkin <mst@redhat.com>
Signed-off-by: NMichael S. Tsirkin <mst@redhat.com>
上级 605d0a94
...@@ -9,7 +9,9 @@ ...@@ -9,7 +9,9 @@
* This work is licensed under the terms of the GNU GPL, version 2 or later. * This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory. * See the COPYING file in the top-level directory.
*/ */
#include "qemu-common.h"
#include "sysemu/hostmem.h" #include "sysemu/hostmem.h"
#include "sysemu/sysemu.h"
#include "qom/object_interfaces.h" #include "qom/object_interfaces.h"
/* hostmem-file.c */ /* hostmem-file.c */
...@@ -46,6 +48,7 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp) ...@@ -46,6 +48,7 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
error_setg(errp, "-mem-path not supported on this host"); error_setg(errp, "-mem-path not supported on this host");
#else #else
if (!memory_region_size(&backend->mr)) { if (!memory_region_size(&backend->mr)) {
backend->force_prealloc = mem_prealloc;
memory_region_init_ram_from_file(&backend->mr, OBJECT(backend), memory_region_init_ram_from_file(&backend->mr, OBJECT(backend),
object_get_canonical_path(OBJECT(backend)), object_get_canonical_path(OBJECT(backend)),
backend->size, backend->size,
......
...@@ -105,6 +105,41 @@ static void host_memory_backend_set_dump(Object *obj, bool value, Error **errp) ...@@ -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) static void host_memory_backend_init(Object *obj)
{ {
HostMemoryBackend *backend = MEMORY_BACKEND(obj); HostMemoryBackend *backend = MEMORY_BACKEND(obj);
...@@ -113,6 +148,7 @@ static void host_memory_backend_init(Object *obj) ...@@ -113,6 +148,7 @@ static void host_memory_backend_init(Object *obj)
"mem-merge", true); "mem-merge", true);
backend->dump = qemu_opt_get_bool(qemu_get_machine_opts(), backend->dump = qemu_opt_get_bool(qemu_get_machine_opts(),
"dump-guest-core", true); "dump-guest-core", true);
backend->prealloc = mem_prealloc;
object_property_add_bool(obj, "merge", object_property_add_bool(obj, "merge",
host_memory_backend_get_merge, host_memory_backend_get_merge,
...@@ -120,6 +156,9 @@ static void host_memory_backend_init(Object *obj) ...@@ -120,6 +156,9 @@ static void host_memory_backend_init(Object *obj)
object_property_add_bool(obj, "dump", object_property_add_bool(obj, "dump",
host_memory_backend_get_dump, host_memory_backend_get_dump,
host_memory_backend_set_dump, NULL); 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", object_property_add(obj, "size", "int",
host_memory_backend_get_size, host_memory_backend_get_size,
host_memory_backend_set_size, NULL, NULL, NULL); host_memory_backend_set_size, NULL, NULL, NULL);
...@@ -165,6 +204,9 @@ host_memory_backend_memory_complete(UserCreatable *uc, Error **errp) ...@@ -165,6 +204,9 @@ host_memory_backend_memory_complete(UserCreatable *uc, Error **errp)
if (!backend->dump) { if (!backend->dump) {
qemu_madvise(ptr, sz, QEMU_MADV_DONTDUMP); qemu_madvise(ptr, sz, QEMU_MADV_DONTDUMP);
} }
if (backend->prealloc) {
os_mem_prealloc(memory_region_get_fd(&backend->mr), ptr, sz);
}
} }
} }
......
...@@ -1448,6 +1448,13 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length) ...@@ -1448,6 +1448,13 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
} }
#endif /* !_WIN32 */ #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. /* Return a host pointer to ram allocated with qemu_ram_alloc.
With the exception of the softmmu code in this file, this should 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, only be used for local memory (e.g. video ram) that the device owns,
......
...@@ -533,6 +533,16 @@ bool memory_region_is_logging(MemoryRegion *mr); ...@@ -533,6 +533,16 @@ bool memory_region_is_logging(MemoryRegion *mr);
*/ */
bool memory_region_is_rom(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. * memory_region_get_ram_ptr: Get a pointer into a RAM memory region.
* *
......
...@@ -27,6 +27,7 @@ ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr, ...@@ -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, ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
MemoryRegion *mr); MemoryRegion *mr);
ram_addr_t qemu_ram_alloc(ram_addr_t size, 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_get_ram_ptr(ram_addr_t addr);
void qemu_ram_free(ram_addr_t addr); void qemu_ram_free(ram_addr_t addr);
void qemu_ram_free_from_ptr(ram_addr_t addr); void qemu_ram_free_from_ptr(ram_addr_t addr);
......
...@@ -53,6 +53,7 @@ struct HostMemoryBackend { ...@@ -53,6 +53,7 @@ struct HostMemoryBackend {
/* protected */ /* protected */
uint64_t size; uint64_t size;
bool merge, dump; bool merge, dump;
bool prealloc, force_prealloc;
MemoryRegion mr; MemoryRegion mr;
}; };
......
...@@ -1271,6 +1271,17 @@ void memory_region_reset_dirty(MemoryRegion *mr, hwaddr addr, ...@@ -1271,6 +1271,17 @@ void memory_region_reset_dirty(MemoryRegion *mr, hwaddr addr,
cpu_physical_memory_reset_dirty(mr->ram_addr + addr, size, client); 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) void *memory_region_get_ram_ptr(MemoryRegion *mr)
{ {
if (mr->alias) { if (mr->alias) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册