Skip to content

Commit

Permalink
hostmem: add property to map memory with MAP_SHARED
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
bonzini authored and mstsirkin committed Jun 19, 2014
1 parent a35ba7b commit dbcb898
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 12 deletions.
26 changes: 25 additions & 1 deletion backends/hostmem-file.c
Expand Up @@ -28,6 +28,8 @@ typedef struct HostMemoryBackendFile HostMemoryBackendFile;

struct HostMemoryBackendFile {
HostMemoryBackend parent_obj;

bool share;
char *mem_path;
};

Expand All @@ -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
Expand Down Expand Up @@ -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);
}
Expand Down
18 changes: 10 additions & 8 deletions exec.c
Expand Up @@ -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);
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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;
Expand All @@ -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) {
Expand Down Expand Up @@ -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 {
Expand Down
2 changes: 2 additions & 0 deletions include/exec/memory.h
Expand Up @@ -321,13 +321,15 @@ 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.
*/
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
Expand Down
3 changes: 2 additions & 1 deletion include/exec/ram_addr.h
Expand Up @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion memory.c
Expand Up @@ -1038,14 +1038,15 @@ 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)
{
memory_region_init(mr, owner, name, size);
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

Expand Down
2 changes: 1 addition & 1 deletion numa.c
Expand Up @@ -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
Expand Down

0 comments on commit dbcb898

Please sign in to comment.