From 3a4641054e320d8ad7e780c30010b1c1dbfc56e8 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Tue, 10 Jan 2017 13:53:14 +0100 Subject: monitor: reuse user_creatable_add_opts() instead of user_creatable_add() Simplify code by dropping ~57LOC by merging user_creatable_add() into user_creatable_add_opts() and using the later from monitor. Along with it allocate opts_visitor_new() once in user_creatable_add_opts(). As result we have one less API func and a more readable/simple user_creatable_add_opts() vs user_creatable_add(). Signed-off-by: Igor Mammedov Reviewed-by: Eric Blake Message-Id: <1484052795-158195-3-git-send-email-imammedo@redhat.com> Signed-off-by: Eduardo Habkost --- include/qom/object_interfaces.h | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'include') diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h index 8b17f4def7..fdd7603c84 100644 --- a/include/qom/object_interfaces.h +++ b/include/qom/object_interfaces.h @@ -75,23 +75,6 @@ void user_creatable_complete(Object *obj, Error **errp); */ bool user_creatable_can_be_deleted(UserCreatable *uc, Error **errp); -/** - * user_creatable_add: - * @qdict: the object definition - * @v: the visitor - * @errp: if an error occurs, a pointer to an area to store the error - * - * Create an instance of the user creatable object whose type - * is defined in @qdict by the 'qom-type' field, placing it - * in the object composition tree with name provided by the - * 'id' field. The remaining fields in @qdict are used to - * initialize the object properties. - * - * Returns: the newly created object or NULL on error - */ -Object *user_creatable_add(const QDict *qdict, - Visitor *v, Error **errp); - /** * user_creatable_add_type: * @type: the object type name -- cgit v1.2.3-55-g7522 From e1ff3c67e8544f41f1bea76ba76385faee0d2bb7 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Tue, 10 Jan 2017 13:53:15 +0100 Subject: monitor: fix qmp/hmp query-memdev not reporting IDs of memory backends Considering 'id' is mandatory for user_creatable objects/backends and user_creatable_add_type() always has it as an argument regardless of where from it is called CLI/monitor or QMP, Fix issue by adding 'id' property to hostmem backends and set it in user_creatable_add_type() for every object that implements 'id' property. Then later at query-memdev time get 'id' from object directly. Signed-off-by: Igor Mammedov Message-Id: <1484052795-158195-4-git-send-email-imammedo@redhat.com> Reviewed-by: Eric Blake Signed-off-by: Eduardo Habkost --- backends/hostmem.c | 26 ++++++++++++++++++++++++++ docs/qmp-commands.txt | 1 + hmp.c | 5 +---- include/sysemu/hostmem.h | 1 + numa.c | 3 +++ qapi-schema.json | 3 +++ qom/object_interfaces.c | 6 ++++++ 7 files changed, 41 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/backends/hostmem.c b/backends/hostmem.c index 4256d24acb..7f5de70609 100644 --- a/backends/hostmem.c +++ b/backends/hostmem.c @@ -348,6 +348,24 @@ host_memory_backend_can_be_deleted(UserCreatable *uc, Error **errp) } } +static char *get_id(Object *o, Error **errp) +{ + HostMemoryBackend *backend = MEMORY_BACKEND(o); + + return g_strdup(backend->id); +} + +static void set_id(Object *o, const char *str, Error **errp) +{ + HostMemoryBackend *backend = MEMORY_BACKEND(o); + + if (backend->id) { + error_setg(errp, "cannot change property value"); + return; + } + backend->id = g_strdup(str); +} + static void host_memory_backend_class_init(ObjectClass *oc, void *data) { @@ -377,6 +395,13 @@ host_memory_backend_class_init(ObjectClass *oc, void *data) HostMemPolicy_lookup, host_memory_backend_get_policy, host_memory_backend_set_policy, &error_abort); + object_class_property_add_str(oc, "id", get_id, set_id, &error_abort); +} + +static void host_memory_backend_finalize(Object *o) +{ + HostMemoryBackend *backend = MEMORY_BACKEND(o); + g_free(backend->id); } static const TypeInfo host_memory_backend_info = { @@ -387,6 +412,7 @@ static const TypeInfo host_memory_backend_info = { .class_init = host_memory_backend_class_init, .instance_size = sizeof(HostMemoryBackend), .instance_init = host_memory_backend_init, + .instance_finalize = host_memory_backend_finalize, .interfaces = (InterfaceInfo[]) { { TYPE_USER_CREATABLE }, { } diff --git a/docs/qmp-commands.txt b/docs/qmp-commands.txt index abf210a596..18db4cdb82 100644 --- a/docs/qmp-commands.txt +++ b/docs/qmp-commands.txt @@ -3529,6 +3529,7 @@ Example (1): "policy": "bind" }, { + "id": "mem1", "size": 536870912, "merge": false, "dump": true, diff --git a/hmp.c b/hmp.c index e7bead5a1d..8522efea26 100644 --- a/hmp.c +++ b/hmp.c @@ -2078,13 +2078,11 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict) MemdevList *m = memdev_list; Visitor *v; char *str; - int i = 0; - while (m) { v = string_output_visitor_new(false, &str); visit_type_uint16List(v, NULL, &m->value->host_nodes, NULL); - monitor_printf(mon, "memory backend: %d\n", i); + monitor_printf(mon, "memory backend: %s\n", m->value->id); monitor_printf(mon, " size: %" PRId64 "\n", m->value->size); monitor_printf(mon, " merge: %s\n", m->value->merge ? "true" : "false"); @@ -2100,7 +2098,6 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict) g_free(str); visit_free(v); m = m->next; - i++; } monitor_printf(mon, "\n"); diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h index 678232af40..ecae0cff19 100644 --- a/include/sysemu/hostmem.h +++ b/include/sysemu/hostmem.h @@ -52,6 +52,7 @@ struct HostMemoryBackend { Object parent; /* protected */ + char *id; uint64_t size; bool merge, dump; bool prealloc, force_prealloc, is_mapped; diff --git a/numa.c b/numa.c index 9c09e45e7d..f5fc7da3e9 100644 --- a/numa.c +++ b/numa.c @@ -518,6 +518,9 @@ 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->has_id = !!m->value->id; + m->value->size = object_property_get_int(obj, "size", &error_abort); m->value->merge = object_property_get_bool(obj, "merge", diff --git a/qapi-schema.json b/qapi-schema.json index eab8d4a9ee..e42998edec 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -4457,6 +4457,8 @@ # # Information about memory backend # +# @id: #optional backend's ID if backend has 'id' property (since 2.9) +# # @size: memory backend size # # @merge: enables or disables memory merge support @@ -4473,6 +4475,7 @@ ## { 'struct': 'Memdev', 'data': { + '*id': 'str', 'size': 'size', 'merge': 'bool', 'dump': 'bool', diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c index 9b4155a227..03a95c3276 100644 --- a/qom/object_interfaces.c +++ b/qom/object_interfaces.c @@ -62,6 +62,12 @@ Object *user_creatable_add_type(const char *type, const char *id, assert(qdict); obj = object_new(type); + if (object_property_find(obj, "id", NULL)) { + object_property_set_str(obj, id, "id", &local_err); + if (local_err) { + goto out; + } + } visit_start_struct(v, NULL, NULL, 0, &local_err); if (local_err) { goto out; -- cgit v1.2.3-55-g7522 From cdda2018e3b9ce0c18938767dfdb1e05a05b67ca Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Fri, 18 Nov 2016 12:02:54 +0100 Subject: numa: make -numa parser dynamically allocate CPUs masks so it won't impose an additional limits on max_cpus limits supported by different targets. It removes global MAX_CPUMASK_BITS constant and need to bump it up whenever max_cpus is being increased for a target above MAX_CPUMASK_BITS value. Use runtime max_cpus value instead to allocate sufficiently sized node_cpu bitmasks in numa parser. Signed-off-by: Igor Mammedov Message-Id: <1479466974-249781-1-git-send-email-imammedo@redhat.com> Reviewed-by: Eduardo Habkost [ehabkost: Added asserts to ensure cpu_index < max_cpus] Signed-off-by: Eduardo Habkost --- include/sysemu/numa.h | 2 +- include/sysemu/sysemu.h | 7 ------- numa.c | 21 ++++++++++++++------- vl.c | 5 ----- 4 files changed, 15 insertions(+), 20 deletions(-) (limited to 'include') diff --git a/include/sysemu/numa.h b/include/sysemu/numa.h index 4da808a6e9..8f09dcf918 100644 --- a/include/sysemu/numa.h +++ b/include/sysemu/numa.h @@ -17,7 +17,7 @@ struct numa_addr_range { typedef struct node_info { uint64_t node_mem; - DECLARE_BITMAP(node_cpu, MAX_CPUMASK_BITS); + unsigned long *node_cpu; struct HostMemoryBackend *node_memdev; bool present; QLIST_HEAD(, numa_addr_range) addr; /* List to store address ranges */ diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index 66c6f1577e..cccde56454 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -168,13 +168,6 @@ extern int mem_prealloc; #define MAX_NODES 128 #define NUMA_NODE_UNASSIGNED MAX_NODES -/* The following shall be true for all CPUs: - * cpu->cpu_index < max_cpus <= MAX_CPUMASK_BITS - * - * Note that cpu->get_arch_id() may be larger than MAX_CPUMASK_BITS. - */ -#define MAX_CPUMASK_BITS 288 - #define MAX_OPTION_ROMS 16 typedef struct QEMUOptionRom { const char *name; diff --git a/numa.c b/numa.c index f5fc7da3e9..379bc8a140 100644 --- a/numa.c +++ b/numa.c @@ -266,20 +266,19 @@ static char *enumerate_cpus(unsigned long *cpus, int max_cpus) static void validate_numa_cpus(void) { int i; - DECLARE_BITMAP(seen_cpus, MAX_CPUMASK_BITS); + unsigned long *seen_cpus = bitmap_new(max_cpus); - bitmap_zero(seen_cpus, MAX_CPUMASK_BITS); for (i = 0; i < nb_numa_nodes; i++) { - if (bitmap_intersects(seen_cpus, numa_info[i].node_cpu, - MAX_CPUMASK_BITS)) { + if (bitmap_intersects(seen_cpus, numa_info[i].node_cpu, max_cpus)) { bitmap_and(seen_cpus, seen_cpus, - numa_info[i].node_cpu, MAX_CPUMASK_BITS); + numa_info[i].node_cpu, max_cpus); error_report("CPU(s) present in multiple NUMA nodes: %s", enumerate_cpus(seen_cpus, max_cpus)); + g_free(seen_cpus); exit(EXIT_FAILURE); } bitmap_or(seen_cpus, seen_cpus, - numa_info[i].node_cpu, MAX_CPUMASK_BITS); + numa_info[i].node_cpu, max_cpus); } if (!bitmap_full(seen_cpus, max_cpus)) { @@ -291,12 +290,17 @@ static void validate_numa_cpus(void) "in NUMA config"); g_free(msg); } + g_free(seen_cpus); } void parse_numa_opts(MachineClass *mc) { int i; + for (i = 0; i < MAX_NODES; i++) { + numa_info[i].node_cpu = bitmap_new(max_cpus); + } + if (qemu_opts_foreach(qemu_find_opts("numa"), parse_numa, NULL, NULL)) { exit(1); } @@ -362,7 +366,7 @@ void parse_numa_opts(MachineClass *mc) numa_set_mem_ranges(); for (i = 0; i < nb_numa_nodes; i++) { - if (!bitmap_empty(numa_info[i].node_cpu, MAX_CPUMASK_BITS)) { + if (!bitmap_empty(numa_info[i].node_cpu, max_cpus)) { break; } } @@ -397,6 +401,7 @@ void numa_post_machine_init(void) CPU_FOREACH(cpu) { for (i = 0; i < nb_numa_nodes; i++) { + assert(cpu->cpu_index < max_cpus); if (test_bit(cpu->cpu_index, numa_info[i].node_cpu)) { cpu->numa_node = i; } @@ -558,6 +563,8 @@ int numa_get_node_for_cpu(int idx) { int i; + assert(idx < max_cpus); + for (i = 0; i < nb_numa_nodes; i++) { if (test_bit(idx, numa_info[i].node_cpu)) { break; diff --git a/vl.c b/vl.c index a23de18fa9..c643d3ff3a 100644 --- a/vl.c +++ b/vl.c @@ -1277,11 +1277,6 @@ static void smp_parse(QemuOpts *opts) max_cpus = qemu_opt_get_number(opts, "maxcpus", cpus); - if (max_cpus > MAX_CPUMASK_BITS) { - error_report("unsupported number of maxcpus"); - exit(1); - } - if (max_cpus < cpus) { error_report("maxcpus must be equal to or greater than smp"); exit(1); -- cgit v1.2.3-55-g7522