Commit 7f56e740 authored by Paolo Bonzini's avatar Paolo Bonzini Committed by Michael S. Tsirkin
Browse files

memory: add error propagation to file-based RAM allocation



Right now, -mem-path will fall back to RAM-based allocation in some
cases.  This should never happen with "-object memory-file", prepare
the code by adding correct error propagation.

Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Signed-off-by: default avatarHu Tao <hutao@cn.fujitsu.com>
Acked-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>

MST: drop \n at end of error messages
parent 0b183fc8
Loading
Loading
Loading
Loading
+24 −12
Original line number Diff line number Diff line
@@ -1016,7 +1016,8 @@ static long gethugepagesize(const char *path)

static void *file_ram_alloc(RAMBlock *block,
                            ram_addr_t memory,
                            const char *path)
                            const char *path,
                            Error **errp)
{
    char *filename;
    char *sanitized_name;
@@ -1035,7 +1036,8 @@ static void *file_ram_alloc(RAMBlock *block,
    }

    if (kvm_enabled() && !kvm_has_sync_mmu()) {
        fprintf(stderr, "host lacks kvm mmu notifiers, -mem-path unsupported\n");
        error_setg(errp,
                   "host lacks kvm mmu notifiers, -mem-path unsupported");
        goto error;
    }

@@ -1052,7 +1054,8 @@ static void *file_ram_alloc(RAMBlock *block,

    fd = mkstemp(filename);
    if (fd < 0) {
        perror("unable to create backing store for hugepages");
        error_setg_errno(errp, errno,
                         "unable to create backing store for hugepages");
        g_free(filename);
        goto error;
    }
@@ -1067,12 +1070,14 @@ static void *file_ram_alloc(RAMBlock *block,
     * If anything goes wrong with it under other filesystems,
     * mmap will fail.
     */
    if (ftruncate(fd, memory))
    if (ftruncate(fd, memory)) {
        perror("ftruncate");
    }

    area = mmap(0, memory, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
    if (area == MAP_FAILED) {
        perror("file_ram_alloc: can't mmap RAM pages");
        error_setg_errno(errp, errno,
                         "unable to map backing store for hugepages");
        close(fd);
        goto error;
    }
@@ -1281,13 +1286,14 @@ 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)
                                    const char *mem_path,
                                    Error **errp)
{
    RAMBlock *new_block;

    if (xen_enabled()) {
        fprintf(stderr, "-mem-path not supported with Xen\n");
        exit(1);
        error_setg(errp, "-mem-path not supported with Xen");
        return -1;
    }

    if (phys_mem_alloc != qemu_anon_ram_alloc) {
@@ -1296,16 +1302,22 @@ ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
         * phys_mem_alloc, but we haven't bothered to provide
         * a hook there.
         */
        fprintf(stderr,
                "-mem-path not supported with this accelerator\n");
        exit(1);
        error_setg(errp,
                   "-mem-path not supported with this accelerator");
        return -1;
    }

    size = TARGET_PAGE_ALIGN(size);
    new_block = g_malloc0(sizeof(*new_block));
    new_block->mr = mr;
    new_block->length = size;
    new_block->host = file_ram_alloc(new_block, size, mem_path);
    new_block->host = file_ram_alloc(new_block, size,
                                     mem_path, errp);
    if (!new_block->host) {
        g_free(new_block);
        return -1;
    }

    return ram_block_add(new_block);
}
#endif
+4 −1
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include "qemu/queue.h"
#include "qemu/int128.h"
#include "qemu/notify.h"
#include "qapi/error.h"

#define MAX_PHYS_ADDR_SPACE_BITS 62
#define MAX_PHYS_ADDR            (((hwaddr)1 << MAX_PHYS_ADDR_SPACE_BITS) - 1)
@@ -321,12 +322,14 @@ void memory_region_init_ram(MemoryRegion *mr,
 * @name: the name of the region.
 * @size: size of the region.
 * @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,
                                      const char *path);
                                      const char *path,
                                      Error **errp);
#endif

/**
+1 −1
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@
#include "hw/xen/xen.h"

ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
                                    const char *mem_path);
                                    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 −2
Original line number Diff line number Diff line
@@ -1038,13 +1038,14 @@ void memory_region_init_ram_from_file(MemoryRegion *mr,
                                      struct Object *owner,
                                      const char *name,
                                      uint64_t size,
                                      const char *path)
                                      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);
    mr->ram_addr = qemu_ram_alloc_from_file(size, mr, path, errp);
}
#endif

+12 −1
Original line number Diff line number Diff line
@@ -230,7 +230,18 @@ static void allocate_system_memory_nonnuma(MemoryRegion *mr, Object *owner,
{
    if (mem_path) {
#ifdef __linux__
        memory_region_init_ram_from_file(mr, owner, name, ram_size, mem_path);
        Error *err = NULL;
        memory_region_init_ram_from_file(mr, owner, name, ram_size,
                                         mem_path, &err);

        /* Legacy behavior: if allocation failed, fall back to
         * regular RAM allocation.
         */
        if (!memory_region_size(mr)) {
            qerror_report_err(err);
            error_free(err);
            memory_region_init_ram(mr, owner, name, ram_size);
        }
#else
        fprintf(stderr, "-mem-path not supported on this host\n");
        exit(1);