mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-10-14 23:13:30 +00:00
hostmem: add property to map memory with MAP_SHARED
A new "share" property can be used with the "memory-file" backend to map memory with MAP_SHARED instead of MAP_PRIVATE. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Hu Tao <hutao@cn.fujitsu.com> Acked-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
a35ba7be4b
commit
dbcb898118
|
@ -28,6 +28,8 @@ typedef struct HostMemoryBackendFile HostMemoryBackendFile;
|
||||||
|
|
||||||
struct HostMemoryBackendFile {
|
struct HostMemoryBackendFile {
|
||||||
HostMemoryBackend parent_obj;
|
HostMemoryBackend parent_obj;
|
||||||
|
|
||||||
|
bool share;
|
||||||
char *mem_path;
|
char *mem_path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -51,7 +53,7 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
|
||||||
backend->force_prealloc = mem_prealloc;
|
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, fb->share,
|
||||||
fb->mem_path, errp);
|
fb->mem_path, errp);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -87,9 +89,31 @@ static void set_mem_path(Object *o, const char *str, Error **errp)
|
||||||
fb->mem_path = g_strdup(str);
|
fb->mem_path = g_strdup(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool file_memory_backend_get_share(Object *o, Error **errp)
|
||||||
|
{
|
||||||
|
HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
|
||||||
|
|
||||||
|
return fb->share;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void file_memory_backend_set_share(Object *o, bool value, Error **errp)
|
||||||
|
{
|
||||||
|
HostMemoryBackend *backend = MEMORY_BACKEND(o);
|
||||||
|
HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
|
||||||
|
|
||||||
|
if (memory_region_size(&backend->mr)) {
|
||||||
|
error_setg(errp, "cannot change property value");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fb->share = value;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
file_backend_instance_init(Object *o)
|
file_backend_instance_init(Object *o)
|
||||||
{
|
{
|
||||||
|
object_property_add_bool(o, "share",
|
||||||
|
file_memory_backend_get_share,
|
||||||
|
file_memory_backend_set_share, NULL);
|
||||||
object_property_add_str(o, "mem-path", get_mem_path,
|
object_property_add_str(o, "mem-path", get_mem_path,
|
||||||
set_mem_path, NULL);
|
set_mem_path, NULL);
|
||||||
}
|
}
|
||||||
|
|
18
exec.c
18
exec.c
|
@ -73,6 +73,9 @@ static MemoryRegion io_mem_unassigned;
|
||||||
/* RAM is pre-allocated and passed into qemu_ram_alloc_from_ptr */
|
/* RAM is pre-allocated and passed into qemu_ram_alloc_from_ptr */
|
||||||
#define RAM_PREALLOC (1 << 0)
|
#define RAM_PREALLOC (1 << 0)
|
||||||
|
|
||||||
|
/* RAM is mmap-ed with MAP_SHARED */
|
||||||
|
#define RAM_SHARED (1 << 1)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct CPUTailQ cpus = QTAILQ_HEAD_INITIALIZER(cpus);
|
struct CPUTailQ cpus = QTAILQ_HEAD_INITIALIZER(cpus);
|
||||||
|
@ -1074,7 +1077,9 @@ static void *file_ram_alloc(RAMBlock *block,
|
||||||
perror("ftruncate");
|
perror("ftruncate");
|
||||||
}
|
}
|
||||||
|
|
||||||
area = mmap(0, memory, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
|
area = mmap(0, memory, PROT_READ | PROT_WRITE,
|
||||||
|
(block->flags & RAM_SHARED ? MAP_SHARED : MAP_PRIVATE),
|
||||||
|
fd, 0);
|
||||||
if (area == MAP_FAILED) {
|
if (area == MAP_FAILED) {
|
||||||
error_setg_errno(errp, errno,
|
error_setg_errno(errp, errno,
|
||||||
"unable to map backing store for hugepages");
|
"unable to map backing store for hugepages");
|
||||||
|
@ -1286,7 +1291,7 @@ static ram_addr_t ram_block_add(RAMBlock *new_block)
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
|
ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
|
||||||
const char *mem_path,
|
bool share, const char *mem_path,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
RAMBlock *new_block;
|
RAMBlock *new_block;
|
||||||
|
@ -1311,6 +1316,7 @@ ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
|
||||||
new_block = g_malloc0(sizeof(*new_block));
|
new_block = g_malloc0(sizeof(*new_block));
|
||||||
new_block->mr = mr;
|
new_block->mr = mr;
|
||||||
new_block->length = size;
|
new_block->length = size;
|
||||||
|
new_block->flags = share ? RAM_SHARED : 0;
|
||||||
new_block->host = file_ram_alloc(new_block, size,
|
new_block->host = file_ram_alloc(new_block, size,
|
||||||
mem_path, errp);
|
mem_path, errp);
|
||||||
if (!new_block->host) {
|
if (!new_block->host) {
|
||||||
|
@ -1413,12 +1419,8 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
|
||||||
flags = MAP_FIXED;
|
flags = MAP_FIXED;
|
||||||
munmap(vaddr, length);
|
munmap(vaddr, length);
|
||||||
if (block->fd >= 0) {
|
if (block->fd >= 0) {
|
||||||
#ifdef MAP_POPULATE
|
flags |= (block->flags & RAM_SHARED ?
|
||||||
flags |= mem_prealloc ? MAP_POPULATE | MAP_SHARED :
|
MAP_SHARED : MAP_PRIVATE);
|
||||||
MAP_PRIVATE;
|
|
||||||
#else
|
|
||||||
flags |= MAP_PRIVATE;
|
|
||||||
#endif
|
|
||||||
area = mmap(vaddr, length, PROT_READ | PROT_WRITE,
|
area = mmap(vaddr, length, PROT_READ | PROT_WRITE,
|
||||||
flags, block->fd, offset);
|
flags, block->fd, offset);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -321,6 +321,7 @@ void memory_region_init_ram(MemoryRegion *mr,
|
||||||
* @owner: the object that tracks the region's reference count
|
* @owner: the object that tracks the region's reference count
|
||||||
* @name: the name of the region.
|
* @name: the name of the region.
|
||||||
* @size: size of the region.
|
* @size: size of the region.
|
||||||
|
* @share: %true if memory must be mmaped with the MAP_SHARED flag
|
||||||
* @path: the path in which to allocate the RAM.
|
* @path: the path in which to allocate the RAM.
|
||||||
* @errp: pointer to Error*, to store an error if it happens.
|
* @errp: pointer to Error*, to store an error if it happens.
|
||||||
*/
|
*/
|
||||||
|
@ -328,6 +329,7 @@ void memory_region_init_ram_from_file(MemoryRegion *mr,
|
||||||
struct Object *owner,
|
struct Object *owner,
|
||||||
const char *name,
|
const char *name,
|
||||||
uint64_t size,
|
uint64_t size,
|
||||||
|
bool share,
|
||||||
const char *path,
|
const char *path,
|
||||||
Error **errp);
|
Error **errp);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -23,7 +23,8 @@
|
||||||
#include "hw/xen/xen.h"
|
#include "hw/xen/xen.h"
|
||||||
|
|
||||||
ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
|
ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
|
||||||
const char *mem_path, Error **errp);
|
bool share, const char *mem_path,
|
||||||
|
Error **errp);
|
||||||
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);
|
||||||
|
|
3
memory.c
3
memory.c
|
@ -1038,6 +1038,7 @@ void memory_region_init_ram_from_file(MemoryRegion *mr,
|
||||||
struct Object *owner,
|
struct Object *owner,
|
||||||
const char *name,
|
const char *name,
|
||||||
uint64_t size,
|
uint64_t size,
|
||||||
|
bool share,
|
||||||
const char *path,
|
const char *path,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
|
@ -1045,7 +1046,7 @@ void memory_region_init_ram_from_file(MemoryRegion *mr,
|
||||||
mr->ram = true;
|
mr->ram = true;
|
||||||
mr->terminates = true;
|
mr->terminates = true;
|
||||||
mr->destructor = memory_region_destructor_ram;
|
mr->destructor = memory_region_destructor_ram;
|
||||||
mr->ram_addr = qemu_ram_alloc_from_file(size, mr, path, errp);
|
mr->ram_addr = qemu_ram_alloc_from_file(size, mr, share, path, errp);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
2
numa.c
2
numa.c
|
@ -231,7 +231,7 @@ static void allocate_system_memory_nonnuma(MemoryRegion *mr, Object *owner,
|
||||||
if (mem_path) {
|
if (mem_path) {
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
Error *err = NULL;
|
Error *err = NULL;
|
||||||
memory_region_init_ram_from_file(mr, owner, name, ram_size,
|
memory_region_init_ram_from_file(mr, owner, name, ram_size, false,
|
||||||
mem_path, &err);
|
mem_path, &err);
|
||||||
|
|
||||||
/* Legacy behavior: if allocation failed, fall back to
|
/* Legacy behavior: if allocation failed, fall back to
|
||||||
|
|
Loading…
Reference in a new issue