diff options
Diffstat (limited to 'hw/core')
| -rw-r--r-- | hw/core/machine-hmp-cmds.c | 3 | ||||
| -rw-r--r-- | hw/core/machine-qmp-cmds.c | 4 | ||||
| -rw-r--r-- | hw/core/machine.c | 88 | ||||
| -rw-r--r-- | hw/core/numa.c | 36 |
4 files changed, 116 insertions, 15 deletions
diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c index 7fa6075f1e..1f66bda346 100644 --- a/hw/core/machine-hmp-cmds.c +++ b/hw/core/machine-hmp-cmds.c @@ -86,6 +86,9 @@ void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict) if (c->has_socket_id) { monitor_printf(mon, " socket-id: \"%" PRIu64 "\"\n", c->socket_id); } + if (c->has_die_id) { + monitor_printf(mon, " die-id: \"%" PRIu64 "\"\n", c->die_id); + } if (c->has_core_id) { monitor_printf(mon, " core-id: \"%" PRIu64 "\"\n", c->core_id); } diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c index 1e08252af7..5bd95b8ab0 100644 --- a/hw/core/machine-qmp-cmds.c +++ b/hw/core/machine-qmp-cmds.c @@ -226,6 +226,8 @@ MachineInfoList *qmp_query_machines(Error **errp) info->name = g_strdup(mc->name); info->cpu_max = !mc->max_cpus ? 1 : mc->max_cpus; info->hotpluggable_cpus = mc->has_hotpluggable_cpus; + info->numa_mem_supported = mc->numa_mem_supported; + info->deprecated = !!mc->deprecation_reason; entry = g_malloc0(sizeof(*entry)); entry->value = info; @@ -264,7 +266,7 @@ void qmp_cpu_add(int64_t id, Error **errp) mc = MACHINE_GET_CLASS(current_machine); if (mc->hot_add_cpu) { - mc->hot_add_cpu(id, errp); + mc->hot_add_cpu(current_machine, id, errp); } else { error_setg(errp, "Not supported"); } diff --git a/hw/core/machine.c b/hw/core/machine.c index ea84bd6788..2be19ec0cd 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -11,6 +11,9 @@ */ #include "qemu/osdep.h" +#include "qemu/option.h" +#include "qapi/qmp/qerror.h" +#include "sysemu/replay.h" #include "qemu/units.h" #include "hw/boards.h" #include "qapi/error.h" @@ -683,6 +686,11 @@ void machine_set_cpu_numa_node(MachineState *machine, return; } + if (props->has_die_id && !slot->props.has_die_id) { + error_setg(errp, "die-id is not supported"); + return; + } + /* skip slots with explicit mismatch */ if (props->has_thread_id && props->thread_id != slot->props.thread_id) { continue; @@ -692,6 +700,10 @@ void machine_set_cpu_numa_node(MachineState *machine, continue; } + if (props->has_die_id && props->die_id != slot->props.die_id) { + continue; + } + if (props->has_socket_id && props->socket_id != slot->props.socket_id) { continue; } @@ -717,6 +729,78 @@ void machine_set_cpu_numa_node(MachineState *machine, } } +static void smp_parse(MachineState *ms, QemuOpts *opts) +{ + if (opts) { + unsigned cpus = qemu_opt_get_number(opts, "cpus", 0); + unsigned sockets = qemu_opt_get_number(opts, "sockets", 0); + unsigned cores = qemu_opt_get_number(opts, "cores", 0); + unsigned threads = qemu_opt_get_number(opts, "threads", 0); + + /* compute missing values, prefer sockets over cores over threads */ + if (cpus == 0 || sockets == 0) { + cores = cores > 0 ? cores : 1; + threads = threads > 0 ? threads : 1; + if (cpus == 0) { + sockets = sockets > 0 ? sockets : 1; + cpus = cores * threads * sockets; + } else { + ms->smp.max_cpus = + qemu_opt_get_number(opts, "maxcpus", cpus); + sockets = ms->smp.max_cpus / (cores * threads); + } + } else if (cores == 0) { + threads = threads > 0 ? threads : 1; + cores = cpus / (sockets * threads); + cores = cores > 0 ? cores : 1; + } else if (threads == 0) { + threads = cpus / (cores * sockets); + threads = threads > 0 ? threads : 1; + } else if (sockets * cores * threads < cpus) { + error_report("cpu topology: " + "sockets (%u) * cores (%u) * threads (%u) < " + "smp_cpus (%u)", + sockets, cores, threads, cpus); + exit(1); + } + + ms->smp.max_cpus = + qemu_opt_get_number(opts, "maxcpus", cpus); + + if (ms->smp.max_cpus < cpus) { + error_report("maxcpus must be equal to or greater than smp"); + exit(1); + } + + if (sockets * cores * threads > ms->smp.max_cpus) { + error_report("cpu topology: " + "sockets (%u) * cores (%u) * threads (%u) > " + "maxcpus (%u)", + sockets, cores, threads, + ms->smp.max_cpus); + exit(1); + } + + if (sockets * cores * threads != ms->smp.max_cpus) { + warn_report("Invalid CPU topology deprecated: " + "sockets (%u) * cores (%u) * threads (%u) " + "!= maxcpus (%u)", + sockets, cores, threads, + ms->smp.max_cpus); + } + + ms->smp.cpus = cpus; + ms->smp.cores = cores; + ms->smp.threads = threads; + } + + if (ms->smp.cpus > 1) { + Error *blocker = NULL; + error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED, "smp"); + replay_add_blocker(blocker); + } +} + static void machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -724,6 +808,7 @@ static void machine_class_init(ObjectClass *oc, void *data) /* Default 128 MB as guest ram size */ mc->default_ram_size = 128 * MiB; mc->rom_file_has_mr = true; + mc->smp_parse = smp_parse; /* numa node memory size aligned on 8MB by default. * On Linux, each node's border has to be 8MB aligned @@ -949,6 +1034,9 @@ static char *cpu_slot_to_string(const CPUArchId *cpu) if (cpu->props.has_socket_id) { g_string_append_printf(s, "socket-id: %"PRId64, cpu->props.socket_id); } + if (cpu->props.has_die_id) { + g_string_append_printf(s, "die-id: %"PRId64, cpu->props.die_id); + } if (cpu->props.has_core_id) { if (s->len) { g_string_append_printf(s, ", "); diff --git a/hw/core/numa.c b/hw/core/numa.c index 66119d181b..a11431483c 100644 --- a/hw/core/numa.c +++ b/hw/core/numa.c @@ -31,6 +31,7 @@ #include "qapi/error.h" #include "qapi/opts-visitor.h" #include "qapi/qapi-visit-machine.h" +#include "sysemu/qtest.h" #include "hw/mem/pc-dimm.h" #include "hw/mem/memory-device.h" #include "qemu/option.h" @@ -44,7 +45,8 @@ QemuOptsList qemu_numa_opts = { .desc = { { 0 } } /* validated with OptsVisitor */ }; -static int have_memdevs = -1; +static int 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 */ @@ -60,6 +62,7 @@ static void parse_numa_node(MachineState *ms, NumaNodeOptions *node, uint16_t nodenr; uint16List *cpus = NULL; MachineClass *mc = MACHINE_GET_CLASS(ms); + unsigned int max_cpus = ms->smp.max_cpus; if (node->has_nodeid) { nodenr = node->nodeid; @@ -101,22 +104,20 @@ static void parse_numa_node(MachineState *ms, NumaNodeOptions *node, } } - if (node->has_mem && node->has_memdev) { - error_setg(errp, "cannot specify both mem= and memdev="); - return; - } - - if (have_memdevs == -1) { - have_memdevs = node->has_memdev; - } - if (node->has_memdev != have_memdevs) { - error_setg(errp, "memdev option must be specified for either " - "all or no nodes"); + have_memdevs = have_memdevs ? : node->has_memdev; + have_mem = have_mem ? : node->has_mem; + if ((node->has_mem && have_memdevs) || (node->has_memdev && have_mem)) { + error_setg(errp, "numa configuration should use either mem= or memdev=," + "mixing both is not allowed"); return; } if (node->has_mem) { numa_info[nodenr].node_mem = node->mem; + if (!qtest_enabled()) { + warn_report("Parameter -numa node,mem is deprecated," + " use -numa node,memdev instead"); + } } if (node->has_memdev) { Object *o; @@ -402,6 +403,11 @@ void numa_complete_configuration(MachineState *ms) if (i == nb_numa_nodes) { assert(mc->numa_auto_assign_ram); mc->numa_auto_assign_ram(mc, numa_info, nb_numa_nodes, ram_size); + if (!qtest_enabled()) { + warn_report("Default splitting of RAM between nodes is deprecated," + " Use '-numa node,memdev' to explictly define RAM" + " allocation per node"); + } } numa_total = 0; @@ -473,8 +479,10 @@ static void allocate_system_memory_nonnuma(MemoryRegion *mr, Object *owner, if (mem_prealloc) { exit(1); } - error_report("falling back to regular RAM allocation."); - + 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"); /* Legacy behavior: if allocation failed, fall back to * regular RAM allocation. */ |