diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2020-02-25 13:31:16 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2020-02-25 13:31:16 +0000 |
commit | db736e0437aa6fd7c1b7e4599c17f9619ab6b837 (patch) | |
tree | d34751ef2c77e5fbc83c19e814c4413b0fa2618a /hw/core/numa.c | |
parent | 9a8abceb5f01d1066d3a1ac5a33aabcbaeec1860 (diff) | |
parent | 9e264985ff0bc86927b44b334bd504687f78659d (diff) |
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* device_del fix (Julia)
* FXAM fix (myself)
* memdev refactoring (Igor)
* memory region API cleanups (Peter, Philippe)
* ioeventfd optimization (Stefan)
* new WHPX maintainer (Sunil)
* Large guest startup optimizations (Chen)
# gpg: Signature made Tue 25 Feb 2020 12:42:24 GMT
# gpg: using RSA key BFFBD25F78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full]
# gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full]
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1
# Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83
* remotes/bonzini/tags/for-upstream: (104 commits)
WHPX: Assigning maintainer for Windows Hypervisor Platform
accel/kvm: Check ioctl(KVM_SET_USER_MEMORY_REGION) return value
target/i386: check for empty register in FXAM
qdev-monitor: Forbid repeated device_del
mem-prealloc: optimize large guest startup
memory: batch allocate ioeventfds[] in address_space_update_ioeventfds()
Avoid cpu_physical_memory_rw() with a constant is_write argument
Let cpu_[physical]_memory() calls pass a boolean 'is_write' argument
exec: Let cpu_[physical]_memory API use a boolean 'is_write' argument
Avoid address_space_rw() with a constant is_write argument
Let address_space_rw() calls pass a boolean 'is_write' argument
exec: Let address_space_unmap() use a boolean 'is_write' argument
hw/virtio: Let vhost_memory_map() use a boolean 'is_write' argument
hw/virtio: Let virtqueue_map_iovec() use a boolean 'is_write' argument
hw/ide: Let the DMAIntFunc prototype use a boolean 'is_write' argument
hw/ide/internal: Remove unused DMARestartFunc typedef
Remove unnecessary cast when using the cpu_[physical]_memory API
exec: Let the cpu_[physical]_memory API use void pointer arguments
Remove unnecessary cast when using the address_space API
hw/net: Avoid casting non-const pointer, use address_space_write()
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/core/numa.c')
-rw-r--r-- | hw/core/numa.c | 101 |
1 files changed, 28 insertions, 73 deletions
diff --git a/hw/core/numa.c b/hw/core/numa.c index 0d1b4be76a..316bc50d75 100644 --- a/hw/core/numa.c +++ b/hw/core/numa.c @@ -52,6 +52,11 @@ QemuOptsList qemu_numa_opts = { }; static int have_memdevs; +bool numa_uses_legacy_mem(void) +{ + return !have_memdevs; +} + static int have_mem; static int max_numa_nodeid; /* Highest specified NUMA node ID, plus one. * For all nodes, nodeid < max_numa_nodeid @@ -652,6 +657,23 @@ void numa_default_auto_assign_ram(MachineClass *mc, NodeInfo *nodes, nodes[i].node_mem = size - usedmem; } +static void numa_init_memdev_container(MachineState *ms, MemoryRegion *ram) +{ + int i; + uint64_t addr = 0; + + for (i = 0; i < ms->numa_state->num_nodes; i++) { + uint64_t size = ms->numa_state->nodes[i].node_mem; + HostMemoryBackend *backend = ms->numa_state->nodes[i].node_memdev; + if (!backend) { + continue; + } + MemoryRegion *seg = machine_consume_memdev(ms, backend); + memory_region_add_subregion(ram, addr, seg); + addr += size; + } +} + void numa_complete_configuration(MachineState *ms) { int i; @@ -734,6 +756,12 @@ void numa_complete_configuration(MachineState *ms) exit(1); } + if (!numa_uses_legacy_mem() && mc->default_ram_id) { + ms->ram = g_new(MemoryRegion, 1); + memory_region_init(ms->ram, OBJECT(ms), mc->default_ram_id, + ram_size); + numa_init_memdev_container(ms, ms->ram); + } /* QEMU needs at least all unique node pair distances to build * the whole NUMA distance table. QEMU treats the distance table * as symmetric by default, i.e. distance A->B == distance B->A. @@ -778,79 +806,6 @@ void numa_cpu_pre_plug(const CPUArchId *slot, DeviceState *dev, Error **errp) } } -static void allocate_system_memory_nonnuma(MemoryRegion *mr, Object *owner, - const char *name, - uint64_t ram_size) -{ - if (mem_path) { -#ifdef __linux__ - Error *err = NULL; - memory_region_init_ram_from_file(mr, owner, name, ram_size, 0, 0, - mem_path, &err); - if (err) { - error_report_err(err); - if (mem_prealloc) { - exit(1); - } - warn_report("falling back to regular RAM allocation"); - error_printf("This is deprecated. Make sure that -mem-path " - " specified path has sufficient resources to allocate" - " -m specified RAM amount\n"); - /* Legacy behavior: if allocation failed, fall back to - * regular RAM allocation. - */ - mem_path = NULL; - memory_region_init_ram_nomigrate(mr, owner, name, ram_size, &error_fatal); - } -#else - fprintf(stderr, "-mem-path not supported on this host\n"); - exit(1); -#endif - } else { - memory_region_init_ram_nomigrate(mr, owner, name, ram_size, &error_fatal); - } - vmstate_register_ram_global(mr); -} - -void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner, - const char *name, - uint64_t ram_size) -{ - uint64_t addr = 0; - int i; - MachineState *ms = MACHINE(qdev_get_machine()); - - if (ms->numa_state == NULL || - ms->numa_state->num_nodes == 0 || !have_memdevs) { - allocate_system_memory_nonnuma(mr, owner, name, ram_size); - return; - } - - memory_region_init(mr, owner, name, ram_size); - for (i = 0; i < ms->numa_state->num_nodes; i++) { - uint64_t size = ms->numa_state->nodes[i].node_mem; - HostMemoryBackend *backend = ms->numa_state->nodes[i].node_memdev; - if (!backend) { - continue; - } - MemoryRegion *seg = host_memory_backend_get_memory(backend); - - if (memory_region_is_mapped(seg)) { - char *path = object_get_canonical_path_component(OBJECT(backend)); - error_report("memory backend %s is used multiple times. Each " - "-numa option must use a different memdev value.", - path); - g_free(path); - exit(1); - } - - host_memory_backend_set_mapped(backend, true); - memory_region_add_subregion(mr, addr, seg); - vmstate_register_ram_global(seg); - addr += size; - } -} - static void numa_stat_memory_devices(NumaNodeMem node_mem[]) { MemoryDeviceInfoList *info_list = qmp_memory_device_list(); |