X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=numa.c;h=3875e1efda3aafb67ce0427cac714bb1bead6f11;hb=dbfc49b69afc616227769f4ab928e452ac7af061;hp=70b150e73a530ad2121633160e61271ac8661c56;hpb=cc8f8ba754bba17eea9791d67b572eb26e30b4ce;p=mirror_qemu.git diff --git a/numa.c b/numa.c index 70b150e73a..3875e1efda 100644 --- a/numa.c +++ b/numa.c @@ -60,6 +60,7 @@ NodeInfo numa_info[MAX_NODES]; static void parse_numa_node(MachineState *ms, NumaNodeOptions *node, Error **errp) { + Error *err = NULL; uint16_t nodenr; uint16List *cpus = NULL; MachineClass *mc = MACHINE_GET_CLASS(ms); @@ -82,8 +83,8 @@ static void parse_numa_node(MachineState *ms, NumaNodeOptions *node, } if (!mc->cpu_index_to_instance_props || !mc->get_default_cpu_node_id) { - error_report("NUMA is not supported by this machine-type"); - exit(1); + error_setg(errp, "NUMA is not supported by this machine-type"); + return; } for (cpus = node->cpus; cpus; cpus = cpus->next) { CpuInstanceProperties props; @@ -97,7 +98,11 @@ static void parse_numa_node(MachineState *ms, NumaNodeOptions *node, props = mc->cpu_index_to_instance_props(ms, cpus->value); props.node_id = nodenr; props.has_node_id = true; - machine_set_cpu_numa_node(ms, &props, &error_fatal); + machine_set_cpu_numa_node(ms, &props, &err); + if (err) { + error_propagate(errp, err); + return; + } } if (node->has_mem && node->has_memdev) { @@ -141,9 +146,8 @@ static void parse_numa_distance(NumaDistOptions *dist, Error **errp) uint8_t val = dist->val; if (src >= MAX_NODES || dst >= MAX_NODES) { - error_setg(errp, - "Invalid node %d, max possible could be %d", - MAX(src, dst), MAX_NODES); + error_setg(errp, "Parameter '%s' expects an integer between 0 and %d", + src >= MAX_NODES ? "src" : "dst", MAX_NODES - 1); return; } @@ -170,28 +174,11 @@ static void parse_numa_distance(NumaDistOptions *dist, Error **errp) have_numa_distance = true; } -static int parse_numa(void *opaque, QemuOpts *opts, Error **errp) +static +void set_numa_options(MachineState *ms, NumaOptions *object, Error **errp) { - NumaOptions *object = NULL; - MachineState *ms = opaque; Error *err = NULL; - { - Visitor *v = opts_visitor_new(opts); - visit_type_NumaOptions(v, NULL, &object, &err); - visit_free(v); - } - - if (err) { - goto end; - } - - /* Fix up legacy suffix-less format */ - if ((object->type == NUMA_OPTIONS_TYPE_NODE) && object->u.node.has_mem) { - const char *mem_str = qemu_opt_get(opts, "mem"); - qemu_strtosz_MiB(mem_str, NULL, &object->u.node.mem); - } - switch (object->type) { case NUMA_OPTIONS_TYPE_NODE: parse_numa_node(ms, &object->u.node, &err); @@ -224,10 +211,35 @@ static int parse_numa(void *opaque, QemuOpts *opts, Error **errp) abort(); } +end: + error_propagate(errp, err); +} + +static int parse_numa(void *opaque, QemuOpts *opts, Error **errp) +{ + NumaOptions *object = NULL; + MachineState *ms = MACHINE(opaque); + Error *err = NULL; + Visitor *v = opts_visitor_new(opts); + + visit_type_NumaOptions(v, NULL, &object, &err); + visit_free(v); + if (err) { + goto end; + } + + /* Fix up legacy suffix-less format */ + if ((object->type == NUMA_OPTIONS_TYPE_NODE) && object->u.node.has_mem) { + const char *mem_str = qemu_opt_get(opts, "mem"); + qemu_strtosz_MiB(mem_str, NULL, &object->u.node.mem); + } + + set_numa_options(ms, object, &err); + end: qapi_free_NumaOptions(object); if (err) { - error_report_err(err); + error_propagate(errp, err); return -1; } @@ -339,15 +351,11 @@ void numa_default_auto_assign_ram(MachineClass *mc, NodeInfo *nodes, nodes[i].node_mem = size - usedmem; } -void parse_numa_opts(MachineState *ms) +void numa_complete_configuration(MachineState *ms) { int i; MachineClass *mc = MACHINE_GET_CLASS(ms); - if (qemu_opts_foreach(qemu_find_opts("numa"), parse_numa, ms, NULL)) { - exit(1); - } - /* * If memory hotplug is enabled (slots > 0) but without '-numa' * options explicitly on CLI, guestes will break. @@ -364,7 +372,7 @@ void parse_numa_opts(MachineState *ms) if (ms->ram_slots > 0 && nb_numa_nodes == 0 && mc->auto_enable_numa_with_memhp) { NumaNodeOptions node = { }; - parse_numa_node(ms, &node, NULL); + parse_numa_node(ms, &node, &error_abort); } assert(max_numa_nodeid <= MAX_NODES); @@ -434,6 +442,22 @@ void parse_numa_opts(MachineState *ms) } } +void parse_numa_opts(MachineState *ms) +{ + qemu_opts_foreach(qemu_find_opts("numa"), parse_numa, ms, &error_fatal); +} + +void qmp_set_numa_node(NumaOptions *cmd, Error **errp) +{ + if (!runstate_check(RUN_STATE_PRECONFIG)) { + error_setg(errp, "The command is permitted only in '%s' state", + RunState_str(RUN_STATE_PRECONFIG)); + return; + } + + set_numa_options(MACHINE(qdev_get_machine()), cmd, errp); +} + void numa_cpu_pre_plug(const CPUArchId *slot, DeviceState *dev, Error **errp) { int node_id = object_property_get_int(OBJECT(dev), "node-id", &error_abort); @@ -458,7 +482,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, 0, false, + memory_region_init_ram_from_file(mr, owner, name, ram_size, 0, 0, mem_path, &err); if (err) { error_report_err(err); @@ -502,14 +526,14 @@ void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner, if (!backend) { continue; } - MemoryRegion *seg = host_memory_backend_get_memory(backend, - &error_fatal); + 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); } @@ -546,10 +570,8 @@ static void numa_stat_memory_devices(NumaNodeMem node_mem[]) if (pcdimm_info) { node_mem[pcdimm_info->node].node_mem += pcdimm_info->size; - if (pcdimm_info->hotpluggable && pcdimm_info->hotplugged) { - node_mem[pcdimm_info->node].node_plugged_mem += - pcdimm_info->size; - } + node_mem[pcdimm_info->node].node_plugged_mem += + pcdimm_info->size; } } } @@ -580,7 +602,7 @@ static int query_memdev(Object *obj, void *opaque) m->value = g_malloc0(sizeof(*m->value)); - m->value->id = object_property_get_str(obj, "id", NULL); + m->value->id = object_get_canonical_path_component(obj); m->value->has_id = !!m->value->id; m->value->size = object_property_get_uint(obj, "size",