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 {
|
||||
HostMemoryBackend parent_obj;
|
||||
|
||||
bool share;
|
||||
char *mem_path;
|
||||
};
|
||||
|
||||
@ -51,7 +53,7 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
|
||||
backend->force_prealloc = mem_prealloc;
|
||||
memory_region_init_ram_from_file(&backend->mr, OBJECT(backend),
|
||||
object_get_canonical_path(OBJECT(backend)),
|
||||
backend->size,
|
||||
backend->size, fb->share,
|
||||
fb->mem_path, errp);
|
||||
}
|
||||
#endif
|
||||
@ -87,9 +89,31 @@ static void set_mem_path(Object *o, const char *str, Error **errp)
|
||||
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
|
||||
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,
|
||||
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 */
|
||||
#define RAM_PREALLOC (1 << 0)
|
||||
|
||||
/* RAM is mmap-ed with MAP_SHARED */
|
||||
#define RAM_SHARED (1 << 1)
|
||||
|
||||
#endif
|
||||
|
||||
struct CPUTailQ cpus = QTAILQ_HEAD_INITIALIZER(cpus);
|
||||
@ -1074,7 +1077,9 @@ static void *file_ram_alloc(RAMBlock *block,
|
||||
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) {
|
||||
error_setg_errno(errp, errno,
|
||||
"unable to map backing store for hugepages");
|
||||
@ -1286,7 +1291,7 @@ static ram_addr_t ram_block_add(RAMBlock *new_block)
|
||||
|
||||
#ifdef __linux__
|
||||
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)
|
||||
{
|
||||
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->mr = mr;
|
||||
new_block->length = size;
|
||||
new_block->flags = share ? RAM_SHARED : 0;
|
||||
new_block->host = file_ram_alloc(new_block, size,
|
||||
mem_path, errp);
|
||||
if (!new_block->host) {
|
||||
@ -1413,12 +1419,8 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
|
||||
flags = MAP_FIXED;
|
||||
munmap(vaddr, length);
|
||||
if (block->fd >= 0) {
|
||||
#ifdef MAP_POPULATE
|
||||
flags |= mem_prealloc ? MAP_POPULATE | MAP_SHARED :
|
||||
MAP_PRIVATE;
|
||||
#else
|
||||
flags |= MAP_PRIVATE;
|
||||
#endif
|
||||
flags |= (block->flags & RAM_SHARED ?
|
||||
MAP_SHARED : MAP_PRIVATE);
|
||||
area = mmap(vaddr, length, PROT_READ | PROT_WRITE,
|
||||
flags, block->fd, offset);
|
||||
} else {
|
||||
|
@ -321,6 +321,7 @@ void memory_region_init_ram(MemoryRegion *mr,
|
||||
* @owner: the object that tracks the region's reference count
|
||||
* @name: the name 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.
|
||||
* @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,
|
||||
const char *name,
|
||||
uint64_t size,
|
||||
bool share,
|
||||
const char *path,
|
||||
Error **errp);
|
||||
#endif
|
||||
|
@ -23,7 +23,8 @@
|
||||
#include "hw/xen/xen.h"
|
||||
|
||||
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,
|
||||
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,
|
||||
const char *name,
|
||||
uint64_t size,
|
||||
bool share,
|
||||
const char *path,
|
||||
Error **errp)
|
||||
{
|
||||
@ -1045,7 +1046,7 @@ void memory_region_init_ram_from_file(MemoryRegion *mr,
|
||||
mr->ram = true;
|
||||
mr->terminates = true;
|
||||
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
|
||||
|
||||
|
2
numa.c
2
numa.c
@ -231,7 +231,7 @@ static void allocate_system_memory_nonnuma(MemoryRegion *mr, Object *owner,
|
||||
if (mem_path) {
|
||||
#ifdef __linux__
|
||||
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);
|
||||
|
||||
/* Legacy behavior: if allocation failed, fall back to
|
||||
|
Loading…
Reference in New Issue
Block a user