Signed-off-by: Chen Fan <chen.fan.f...@cn.fujitsu.com> --- include/qom/node.h | 66 +++++++++++++++++++++++ qom/Makefile.objs | 2 +- qom/node.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 223 insertions(+), 1 deletion(-) create mode 100644 include/qom/node.h create mode 100644 qom/node.c
diff --git a/include/qom/node.h b/include/qom/node.h new file mode 100644 index 0000000..6c948ec --- /dev/null +++ b/include/qom/node.h @@ -0,0 +1,66 @@ +/* + * QEMU System Emulator + * + * Copyright (c) 2013 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 "hw/qdev-core.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) + +Object *object_get_thread_from_index(int64_t cpu_index); + +typedef struct ThreadState { + /*< private >*/ + Object parent_obj; + /*< public >*/ + CPUState **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; diff --git a/qom/Makefile.objs b/qom/Makefile.objs index 985003b..5863919 100644 --- a/qom/Makefile.objs +++ b/qom/Makefile.objs @@ -1,3 +1,3 @@ common-obj-y = object.o container.o qom-qobject.o -common-obj-y += cpu.o +common-obj-y += cpu.o node.o common-obj-y += object_interfaces.o diff --git a/qom/node.c b/qom/node.c new file mode 100644 index 0000000..a335992 --- /dev/null +++ b/qom/node.c @@ -0,0 +1,156 @@ +/* + * QEMU System Emulator + * + * Copyright (c) 2013 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 "qom/cpu.h" +#include "qom/node.h" + +Object *object_get_thread_from_index(int64_t cpu_index) +{ + gchar *path; + Object *thread; + int nodes, cpus_pre_nodes, smp_sockets; + unsigned node_id, socket_id, core_id, thread_id; + unsigned core_index, socket_index; + + nodes = nb_numa_nodes ? nb_numa_nodes : 1; + cpus_pre_nodes = max_cpus / nodes; + smp_sockets = cpus_pre_nodes / (smp_cores * smp_threads); + + core_index = cpu_index / smp_threads; + thread_id = cpu_index % smp_threads; + socket_index = core_index / smp_cores; + core_id = core_index % smp_cores; + node_id = socket_index / smp_sockets; + socket_id = socket_index % smp_sockets; + + path = g_strdup_printf("/machine/node[%d]/socket[%d]/core[%d]/thread[%d]", + node_id, socket_id, core_id, thread_id); + thread = object_resolve_path(path, NULL); + g_free(path); + + return thread; +} + +static void thread_initfn(Object *obj) +{ + ThreadState *ts = THREAD(obj); + + ts->cpu = g_malloc0(sizeof(CPUState *)); + + object_ref(OBJECT(ts->cpu)); + object_property_add_link(obj, "cpu", TYPE_CPU, (Object **)ts->cpu, NULL); +} + +static const TypeInfo thread_type_info = { + .name = TYPE_THREAD, + .parent = TYPE_OBJECT, + .instance_size = sizeof(ThreadState), + .instance_init = thread_initfn, +}; + +static void core_initfn(Object *obj) +{ + int i; + Object *thread_obj; + gchar *thread_name; + + for (i = 0; i < smp_threads; i++) { + thread_obj = object_new(TYPE_THREAD); + thread_name = g_strdup_printf("thread[%" PRIi32 "]", i); + object_property_add_child(obj, thread_name, thread_obj, NULL); + g_free(thread_name); + } +} + +static const TypeInfo core_type_info = { + .name = TYPE_CORE, + .parent = TYPE_OBJECT, + .instance_size = sizeof(CoreState), + .instance_init = core_initfn, +}; + +static void socket_initfn(Object *obj) +{ + int i; + Object *core_obj; + gchar *core_name; + + for (i = 0; i < smp_cores; i++) { + core_obj = object_new(TYPE_CORE); + core_name = g_strdup_printf("core[%" PRIi32 "]", i); + object_property_add_child(obj, core_name, core_obj, NULL); + g_free(core_name); + } +} + +static const TypeInfo socket_type_info = { + .name = TYPE_SOCKET, + .parent = TYPE_OBJECT, + .instance_size = sizeof(SocketState), + .instance_init = socket_initfn, +}; + +static void node_initfn(Object *obj) +{ + int smp_sockets, sockets_pre_node, nodes; + int i; + Object *socket_obj; + gchar *socket_name; + + smp_sockets = max_cpus / (smp_cores * smp_threads); + + nodes = nb_numa_nodes ? nb_numa_nodes : 1; + + sockets_pre_node = smp_sockets / nodes; + + for (i = 0; i < sockets_pre_node; i++) { + socket_obj = object_new(TYPE_SOCKET); + socket_name = g_strdup_printf("socket[%" PRIi32 "]", i); + object_property_add_child(obj, socket_name, socket_obj, NULL); + g_free(socket_name); + } +} + +static const TypeInfo node_type_info = { + .name = TYPE_NODE, + .parent = TYPE_OBJECT, + .instance_size = sizeof(NodeState), + .instance_init = node_initfn, +}; + +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) -- 1.8.1.4