diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2020-02-25 09:19:00 +0100 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2020-02-25 09:19:00 +0100 |
commit | ca6155c0f2bd39b4b4162533be401c98bd960820 (patch) | |
tree | 7e5212409c90fa40b6a50923557f2083c23637ba /softmmu/vl.c | |
parent | c220cdec4845f305034330f80ce297f1f997f2d3 (diff) | |
parent | 9584b564198193bd54f00a01ed7e039d4f03fa31 (diff) |
Merge tag 'patchew/20200219160953.13771-1-imammedo@redhat.com' of https://github.com/patchew-project/qemu into HEAD
This series removes ad hoc RAM allocation API (memory_region_allocate_system_memory)
and consolidates it around hostmem backend. It allows to
* resolve conflicts between global -mem-prealloc and hostmem's "policy" option,
fixing premature allocation before binding policy is applied
* simplify complicated memory allocation routines which had to deal with 2 ways
to allocate RAM.
* reuse hostmem backends of a choice for main RAM without adding extra CLI
options to duplicate hostmem features. A recent case was -mem-shared, to
enable vhost-user on targets that don't support hostmem backends [1] (ex: s390)
* move RAM allocation from individual boards into generic machine code and
provide them with prepared MemoryRegion.
* clean up deprecated NUMA features which were tied to the old API (see patches)
- "numa: remove deprecated -mem-path fallback to anonymous RAM"
- (POSTPONED, waiting on libvirt side) "forbid '-numa node,mem' for 5.0 and newer machine types"
- (POSTPONED) "numa: remove deprecated implicit RAM distribution between nodes"
Introduce a new machine.memory-backend property and wrapper code that aliases
global -mem-path and -mem-alloc into automatically created hostmem backend
properties (provided memory-backend was not set explicitly given by user).
A bulk of trivial patches then follow to incrementally convert individual
boards to using machine.memory-backend provided MemoryRegion.
Board conversion typically involves:
* providing MachineClass::default_ram_size and MachineClass::default_ram_id
so generic code could create default backend if user didn't explicitly provide
memory-backend or -m options
* dropping memory_region_allocate_system_memory() call
* using convenience MachineState::ram MemoryRegion, which points to MemoryRegion
allocated by ram-memdev
On top of that for some boards:
* missing ram_size checks are added (typically it were boards with fixed ram size)
* ram_size fixups are replaced by checks and hard errors, forcing user to
provide correct "-m" values instead of ignoring it and continuing running.
After all boards are converted, the old API is removed and memory allocation
routines are cleaned up.
Diffstat (limited to 'softmmu/vl.c')
-rw-r--r-- | softmmu/vl.c | 78 |
1 files changed, 63 insertions, 15 deletions
diff --git a/softmmu/vl.c b/softmmu/vl.c index 92c7b3a6e9..a9cce78f45 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -56,6 +56,7 @@ #include "ui/input.h" #include "sysemu/sysemu.h" #include "sysemu/numa.h" +#include "sysemu/hostmem.h" #include "exec/gdbstub.h" #include "qemu/timer.h" #include "chardev/char.h" @@ -120,8 +121,6 @@ enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB; int display_opengl; const char* keyboard_layout = NULL; ram_addr_t ram_size; -const char *mem_path = NULL; -int mem_prealloc = 0; /* force preallocation of physical target memory */ bool enable_mlock = false; bool enable_cpu_pm = false; int nb_nics; @@ -2635,6 +2634,29 @@ static void set_memory_options(uint64_t *ram_slots, ram_addr_t *maxram_size, exit(EXIT_FAILURE); } + if (current_machine->ram_memdev_id) { + Object *backend; + ram_addr_t backend_size; + + backend = object_resolve_path_type(current_machine->ram_memdev_id, + TYPE_MEMORY_BACKEND, NULL); + backend_size = object_property_get_uint(backend, "size", &error_abort); + if (mem_str && backend_size != ram_size) { + error_report("Size specified by -m option must match size of " + "explicitly specified 'memory-backend' property"); + exit(EXIT_FAILURE); + } + ram_size = backend_size; + } + + if (!xen_enabled()) { + /* On 32-bit hosts, QEMU is limited by virtual address space */ + if (ram_size > (2047 << 20) && HOST_LONG_BITS == 32) { + error_report("at most 2047 MB RAM can be simulated"); + exit(1); + } + } + loc_pop(&loc); } @@ -2786,6 +2808,24 @@ static void configure_accelerators(const char *progname) } } +static void create_default_memdev(MachineState *ms, const char *path) +{ + Object *obj; + MachineClass *mc = MACHINE_GET_CLASS(ms); + + obj = object_new(path ? TYPE_MEMORY_BACKEND_FILE : TYPE_MEMORY_BACKEND_RAM); + if (path) { + object_property_set_str(obj, path, "mem-path", &error_fatal); + } + object_property_set_int(obj, ms->ram_size, "size", &error_fatal); + object_property_add_child(object_get_objects_root(), mc->default_ram_id, + obj, &error_fatal); + user_creatable_complete(USER_CREATABLE(obj), &error_fatal); + object_unref(obj); + object_property_set_str(OBJECT(ms), mc->default_ram_id, "memory-backend", + &error_fatal); +} + void qemu_init(int argc, char **argv, char **envp) { int i; @@ -2820,8 +2860,10 @@ void qemu_init(int argc, char **argv, char **envp) Error *err = NULL; bool list_data_dirs = false; char *dir, **dirs; + const char *mem_path = NULL; BlockdevOptionsQueue bdo_queue = QSIMPLEQ_HEAD_INITIALIZER(bdo_queue); QemuPluginList plugin_list = QTAILQ_HEAD_INITIALIZER(plugin_list); + int mem_prealloc = 0; /* force preallocation of physical target memory */ os_set_line_buffering(); @@ -3779,8 +3821,6 @@ void qemu_init(int argc, char **argv, char **envp) machine_class = select_machine(); object_set_machine_compat_props(machine_class->compat_props); - set_memory_options(&ram_slots, &maxram_size, machine_class); - os_daemonize(); /* @@ -3929,6 +3969,15 @@ void qemu_init(int argc, char **argv, char **envp) exit(1); } + if (mem_prealloc) { + char *val; + + val = g_strdup_printf("%d", current_machine->smp.cpus); + object_register_sugar_prop("memory-backend", "prealloc-threads", val); + g_free(val); + object_register_sugar_prop("memory-backend", "prealloc", "on"); + } + /* * Get the default machine options from the machine if it is not already * specified either by the configuration file or by the command line. @@ -4092,9 +4141,6 @@ void qemu_init(int argc, char **argv, char **envp) machine_opts = qemu_get_machine_opts(); qemu_opt_foreach(machine_opts, machine_set_property, current_machine, &error_fatal); - current_machine->ram_size = ram_size; - current_machine->maxram_size = maxram_size; - current_machine->ram_slots = ram_slots; /* * Note: uses machine properties such as kernel-irqchip, must run @@ -4205,14 +4251,6 @@ void qemu_init(int argc, char **argv, char **envp) tpm_init(); - if (!xen_enabled()) { - /* On 32-bit hosts, QEMU is limited by virtual address space */ - if (ram_size > (2047 << 20) && HOST_LONG_BITS == 32) { - error_report("at most 2047 MB RAM can be simulated"); - exit(1); - } - } - blk_mig_init(); ram_mig_init(); dirty_bitmap_mig_init(); @@ -4257,8 +4295,18 @@ void qemu_init(int argc, char **argv, char **envp) if (cpu_option) { current_machine->cpu_type = parse_cpu_option(cpu_option); } + + set_memory_options(&ram_slots, &maxram_size, machine_class); + current_machine->ram_size = ram_size; + current_machine->maxram_size = maxram_size; + current_machine->ram_slots = ram_slots; + parse_numa_opts(current_machine); + if (machine_class->default_ram_id && current_machine->ram_size && + numa_uses_legacy_mem() && !current_machine->ram_memdev_id) { + create_default_memdev(current_machine, mem_path); + } /* do monitor/qmp handling at preconfig state if requested */ qemu_main_loop(); |