add cpu-topology.h cpu-topology.c files for prebuild cpu qom tree "/machine/node[X]/socket[Y]/core[Z]/thread[N]/cpu"
Signed-off-by: Chen Fan <chen.fan.f...@cn.fujitsu.com> --- hw/i386/pc.c | 6 +- target-i386/Makefile.objs | 2 +- target-i386/cpu-qom.h | 1 + target-i386/cpu-topology.c | 163 +++++++++++++++++++++++++++++++++++++++++++++ target-i386/cpu-topology.h | 71 ++++++++++++++++++++ target-i386/cpu.c | 29 ++++++++ target-i386/cpu.h | 2 + 7 files changed, 272 insertions(+), 2 deletions(-) create mode 100644 target-i386/cpu-topology.c create mode 100644 target-i386/cpu-topology.h diff --git a/hw/i386/pc.c b/hw/i386/pc.c index a4d539e..6beeb82 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -942,7 +942,7 @@ static X86CPU *pc_new_cpu(const char *cpu_model, X86TopoInfo *topo, object_property_set_int(OBJECT(cpu), apic_id, "apic-id", &local_err); object_property_set_bool(OBJECT(cpu), true, "realized", &local_err); - + x86_topo_cpu_set_link(topo, OBJECT(cpu)); if (local_err) { error_propagate(errp, local_err); object_unref(OBJECT(cpu)); @@ -999,6 +999,10 @@ void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge) } current_cpu_model = cpu_model; + for (i = 0; i < max_cpus; i++) { + x86_topo_cpu_create(i); + } + for (i = 0; i < smp_cpus; i++) { X86TopoInfo *topo = x86_cpu_topo_from_index(i); cpu = pc_new_cpu(cpu_model, topo, icc_bridge, &error); diff --git a/target-i386/Makefile.objs b/target-i386/Makefile.objs index 027b94e..c150ad1 100644 --- a/target-i386/Makefile.objs +++ b/target-i386/Makefile.objs @@ -1,4 +1,4 @@ -obj-y += translate.o helper.o cpu.o +obj-y += translate.o helper.o cpu.o cpu-topology.c obj-y += excp_helper.o fpu_helper.o cc_helper.o int_helper.o svm_helper.o obj-y += smm_helper.o misc_helper.o mem_helper.o seg_helper.o obj-y += gdbstub.o diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h index 722f11a..12818a5 100644 --- a/target-i386/cpu-qom.h +++ b/target-i386/cpu-qom.h @@ -23,6 +23,7 @@ #include "qom/cpu.h" #include "cpu.h" #include "qapi/error.h" +#include "cpu-topology.h" #ifdef TARGET_X86_64 #define TYPE_X86_CPU "x86_64-cpu" diff --git a/target-i386/cpu-topology.c b/target-i386/cpu-topology.c new file mode 100644 index 0000000..b2f90c4 --- /dev/null +++ b/target-i386/cpu-topology.c @@ -0,0 +1,163 @@ +/* + * QEMU System Emulator + * + * Copyright (c) 2014 Fujitsu Ltd. + * Author: Chen Fan <chen.fan.f...@cn.fujitsu.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "qom/object.h" +#include "qemu/module.h" +#include "hw/hw.h" +#include "sysemu/cpus.h" +#include "sysemu/sysemu.h" +#include "cpu-topology.h" + +static NodeState *cpu_topo_node_get(unsigned cpu_index) +{ + int i, node_id = 0; + gchar *name; + char path[128] = "/machine/"; + Object *node; + + for (i = 0; i < nb_numa_nodes; i++) { + if (test_bit(cpu_index, node_cpumask[i])) { + node_id = i; + break; + } + } + + name = g_strdup_printf("node[%" PRIu32 "]", node_id); + pstrcat(path, sizeof(path), name); + node = object_resolve_path(path, NULL); + if (!node) { + node = object_new(TYPE_NODE); + object_property_add_child(qdev_get_machine(), name, + node, NULL); + } + g_free(name); + + return NODE(node); +} + +static SocketState *cpu_topo_socket_get(X86TopoInfo *topo) +{ + gchar *name; + NodeState *node; + Object *socket; + + name = g_strdup_printf("socket[%" PRIu32 "]", topo->pkg_id); + node = cpu_topo_node_get(topo->cpu_index); + socket = object_resolve_path_component(OBJECT(node), name); + if (!socket) { + socket = object_new(TYPE_SOCKET); + object_property_add_child(OBJECT(node), name, socket, NULL); + } + g_free(name); + + return SOCKET(socket); +} + +static CoreState *cpu_topo_core_get(X86TopoInfo *topo) +{ + gchar *name; + SocketState *socket; + Object *core; + + name = g_strdup_printf("core[%" PRIu32 "]", topo->core_id); + socket = cpu_topo_socket_get(topo); + core = object_resolve_path_component(OBJECT(socket), name); + if (!core) { + core = object_new(TYPE_CORE); + object_property_add_child(OBJECT(socket), name, core, NULL); + } + g_free(name); + + return CORE(core); +} + +ThreadState *cpu_topo_thread_get(X86TopoInfo *topo) +{ + gchar *name; + CoreState *core; + Object *thread; + + name = g_strdup_printf("thread[%" PRIu32 "]", topo->smt_id); + + core = cpu_topo_core_get(topo); + thread = object_resolve_path_component(OBJECT(core), name); + if (!thread) { + thread = object_new(TYPE_THREAD); + object_property_add_child(OBJECT(core), name, thread, NULL); + } + g_free(name); + + return THREAD(thread); +} + +static void thread_initfn(Object *obj) +{ + ThreadState *ts = THREAD(obj); + + ts->link_cpu = g_malloc0(sizeof(CPUState*)); +} + +static void thread_fini(Object *obj) +{ + ThreadState *ts = THREAD(obj); + + g_free(ts->link_cpu); +} + +static const TypeInfo thread_type_info = { + .name = TYPE_THREAD, + .parent = TYPE_OBJECT, + .instance_size = sizeof(ThreadState), + .instance_init = thread_initfn, + .instance_finalize = thread_fini, +}; + +static const TypeInfo core_type_info = { + .name = TYPE_CORE, + .parent = TYPE_OBJECT, + .instance_size = sizeof(CoreState), +}; + +static const TypeInfo socket_type_info = { + .name = TYPE_SOCKET, + .parent = TYPE_OBJECT, + .instance_size = sizeof(SocketState), +}; + +static const TypeInfo node_type_info = { + .name = TYPE_NODE, + .parent = TYPE_OBJECT, + .instance_size = sizeof(NodeState), +}; + +static void node_register_types(void) +{ + type_register_static(&node_type_info); + type_register_static(&socket_type_info); + type_register_static(&core_type_info); + type_register_static(&thread_type_info); +} + +type_init(node_register_types) diff --git a/target-i386/cpu-topology.h b/target-i386/cpu-topology.h new file mode 100644 index 0000000..16f7312 --- /dev/null +++ b/target-i386/cpu-topology.h @@ -0,0 +1,71 @@ +/* + * QEMU System Emulator + * + * Copyright (c) 2014 Fujitsu Ltd. + * Author: Chen Fan <chen.fan.f...@cn.fujitsu.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef TARGET_I386_CPU_TOPOLOGY_H +#define TARGET_I386_CPU_TOPOLOGY_H + +#include "hw/qdev-core.h" +#include "topology.h" + +#define TYPE_NODE "node" +#define TYPE_SOCKET "socket" +#define TYPE_CORE "core" +#define TYPE_THREAD "thread" + +#define NODE(obj) OBJECT_CHECK(NodeState, (obj), TYPE_NODE) + +#define SOCKET(obj) OBJECT_CHECK(SocketState, (obj), TYPE_SOCKET) + +#define CORE(obj) OBJECT_CHECK(CoreState, (obj), TYPE_CORE) + +#define THREAD(obj) OBJECT_CHECK(ThreadState, (obj), TYPE_THREAD) + +typedef struct ThreadState { + /*< private >*/ + Object parent_obj; + /*< public >*/ + CPUState **link_cpu; +} ThreadState; + +typedef struct CoreState { + /*< private >*/ + Object parent_obj; + /*< public >*/ +} CoreState; + +typedef struct SocketState { + /*< private >*/ + Object parent_obj; + /*< public >*/ +} SocketState; + +typedef struct NodeState { + /*< private >*/ + Object parent_obj; + /*< public >*/ +} NodeState; + +ThreadState *cpu_topo_thread_get(X86TopoInfo *topo); + +#endif /* TARGET_I386_CPU_TOPOLOGY_H */ diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 1858a66..c1a2ba3 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2711,6 +2711,35 @@ static void x86_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb) cpu->env.eip = tb->pc - tb->cs_base; } +void x86_topo_cpu_set_link(X86TopoInfo *topo, Object *obj) +{ + gchar *name; + ThreadState *thread; + + name = g_strdup_printf("cpu[%" PRIu32 "]", + x86_cpu_apic_id_from_index(topo->cpu_index)); + + thread = cpu_topo_thread_get(topo); + object_property_set_link(OBJECT(thread), obj, name, NULL); + g_free(name); +} + +void x86_topo_cpu_create(unsigned int cpu_index) +{ + X86TopoInfo *topo = x86_cpu_topo_from_index(cpu_index); + ThreadState *thread; + gchar *name; + + thread = cpu_topo_thread_get(topo); + + name = g_strdup_printf("cpu[%" PRIu32 "]", + x86_cpu_apic_id_from_index(cpu_index)); + + object_property_add_link(OBJECT(thread), name, TYPE_CPU, + (Object **)thread->link_cpu, NULL); + g_free(name); +} + static Property x86_cpu_properties[] = { DEFINE_PROP_BOOL("pmu", X86CPU, enable_pmu, false), { .name = "hv-spinlocks", .info = &qdev_prop_spinlocks }, diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 1647394..29fa730 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -1286,6 +1286,8 @@ void enable_compat_apic_id_mode(void); #include "topology.h" X86TopoInfo *x86_cpu_topo_from_index(unsigned int cpu_index); +void x86_topo_cpu_create(unsigned int cpu_index); +void x86_topo_cpu_set_link(X86TopoInfo *topo, Object *obj); #define APIC_DEFAULT_ADDRESS 0xfee00000 #define APIC_SPACE_SIZE 0x100000 -- 1.8.1.4