1 | /* |
2 | * HMP commands related to machines and CPUs |
3 | * |
4 | * Copyright IBM, Corp. 2011 |
5 | * |
6 | * Authors: |
7 | * Anthony Liguori <aliguori@us.ibm.com> |
8 | * |
9 | * This work is licensed under the terms of the GNU GPL, version 2. See |
10 | * the COPYING file in the top-level directory. |
11 | * |
12 | * Contributions after 2012-01-13 are licensed under the terms of the |
13 | * GNU GPL, version 2 or (at your option) any later version. |
14 | */ |
15 | |
16 | #include "qemu/osdep.h" |
17 | #include "monitor/hmp.h" |
18 | #include "monitor/monitor.h" |
19 | #include "qapi/error.h" |
20 | #include "qapi/qapi-builtin-visit.h" |
21 | #include "qapi/qapi-commands-machine.h" |
22 | #include "qapi/qmp/qdict.h" |
23 | #include "qapi/string-output-visitor.h" |
24 | #include "qemu/error-report.h" |
25 | #include "sysemu/numa.h" |
26 | #include "hw/boards.h" |
27 | |
28 | void hmp_info_cpus(Monitor *mon, const QDict *qdict) |
29 | { |
30 | CpuInfoFastList *cpu_list, *cpu; |
31 | |
32 | cpu_list = qmp_query_cpus_fast(NULL); |
33 | |
34 | for (cpu = cpu_list; cpu; cpu = cpu->next) { |
35 | int active = ' '; |
36 | |
37 | if (cpu->value->cpu_index == monitor_get_cpu_index()) { |
38 | active = '*'; |
39 | } |
40 | |
41 | monitor_printf(mon, "%c CPU #%" PRId64 ":" , active, |
42 | cpu->value->cpu_index); |
43 | monitor_printf(mon, " thread_id=%" PRId64 "\n" , cpu->value->thread_id); |
44 | } |
45 | |
46 | qapi_free_CpuInfoFastList(cpu_list); |
47 | } |
48 | |
49 | void hmp_cpu_add(Monitor *mon, const QDict *qdict) |
50 | { |
51 | int cpuid; |
52 | Error *err = NULL; |
53 | |
54 | error_report("cpu_add is deprecated, please use device_add instead" ); |
55 | |
56 | cpuid = qdict_get_int(qdict, "id" ); |
57 | qmp_cpu_add(cpuid, &err); |
58 | hmp_handle_error(mon, &err); |
59 | } |
60 | |
61 | void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict) |
62 | { |
63 | Error *err = NULL; |
64 | HotpluggableCPUList *l = qmp_query_hotpluggable_cpus(&err); |
65 | HotpluggableCPUList *saved = l; |
66 | CpuInstanceProperties *c; |
67 | |
68 | if (err != NULL) { |
69 | hmp_handle_error(mon, &err); |
70 | return; |
71 | } |
72 | |
73 | monitor_printf(mon, "Hotpluggable CPUs:\n" ); |
74 | while (l) { |
75 | monitor_printf(mon, " type: \"%s\"\n" , l->value->type); |
76 | monitor_printf(mon, " vcpus_count: \"%" PRIu64 "\"\n" , |
77 | l->value->vcpus_count); |
78 | if (l->value->has_qom_path) { |
79 | monitor_printf(mon, " qom_path: \"%s\"\n" , l->value->qom_path); |
80 | } |
81 | |
82 | c = l->value->props; |
83 | monitor_printf(mon, " CPUInstance Properties:\n" ); |
84 | if (c->has_node_id) { |
85 | monitor_printf(mon, " node-id: \"%" PRIu64 "\"\n" , c->node_id); |
86 | } |
87 | if (c->has_socket_id) { |
88 | monitor_printf(mon, " socket-id: \"%" PRIu64 "\"\n" , c->socket_id); |
89 | } |
90 | if (c->has_die_id) { |
91 | monitor_printf(mon, " die-id: \"%" PRIu64 "\"\n" , c->die_id); |
92 | } |
93 | if (c->has_core_id) { |
94 | monitor_printf(mon, " core-id: \"%" PRIu64 "\"\n" , c->core_id); |
95 | } |
96 | if (c->has_thread_id) { |
97 | monitor_printf(mon, " thread-id: \"%" PRIu64 "\"\n" , c->thread_id); |
98 | } |
99 | |
100 | l = l->next; |
101 | } |
102 | |
103 | qapi_free_HotpluggableCPUList(saved); |
104 | } |
105 | |
106 | void hmp_info_memdev(Monitor *mon, const QDict *qdict) |
107 | { |
108 | Error *err = NULL; |
109 | MemdevList *memdev_list = qmp_query_memdev(&err); |
110 | MemdevList *m = memdev_list; |
111 | Visitor *v; |
112 | char *str; |
113 | |
114 | while (m) { |
115 | v = string_output_visitor_new(false, &str); |
116 | visit_type_uint16List(v, NULL, &m->value->host_nodes, NULL); |
117 | monitor_printf(mon, "memory backend: %s\n" , m->value->id); |
118 | monitor_printf(mon, " size: %" PRId64 "\n" , m->value->size); |
119 | monitor_printf(mon, " merge: %s\n" , |
120 | m->value->merge ? "true" : "false" ); |
121 | monitor_printf(mon, " dump: %s\n" , |
122 | m->value->dump ? "true" : "false" ); |
123 | monitor_printf(mon, " prealloc: %s\n" , |
124 | m->value->prealloc ? "true" : "false" ); |
125 | monitor_printf(mon, " policy: %s\n" , |
126 | HostMemPolicy_str(m->value->policy)); |
127 | visit_complete(v, &str); |
128 | monitor_printf(mon, " host nodes: %s\n" , str); |
129 | |
130 | g_free(str); |
131 | visit_free(v); |
132 | m = m->next; |
133 | } |
134 | |
135 | monitor_printf(mon, "\n" ); |
136 | |
137 | qapi_free_MemdevList(memdev_list); |
138 | hmp_handle_error(mon, &err); |
139 | } |
140 | |
141 | void hmp_info_numa(Monitor *mon, const QDict *qdict) |
142 | { |
143 | int i, nb_numa_nodes; |
144 | NumaNodeMem *node_mem; |
145 | CpuInfoList *cpu_list, *cpu; |
146 | MachineState *ms = MACHINE(qdev_get_machine()); |
147 | |
148 | nb_numa_nodes = ms->numa_state ? ms->numa_state->num_nodes : 0; |
149 | monitor_printf(mon, "%d nodes\n" , nb_numa_nodes); |
150 | if (!nb_numa_nodes) { |
151 | return; |
152 | } |
153 | |
154 | cpu_list = qmp_query_cpus(&error_abort); |
155 | node_mem = g_new0(NumaNodeMem, nb_numa_nodes); |
156 | |
157 | query_numa_node_mem(node_mem, ms); |
158 | for (i = 0; i < nb_numa_nodes; i++) { |
159 | monitor_printf(mon, "node %d cpus:" , i); |
160 | for (cpu = cpu_list; cpu; cpu = cpu->next) { |
161 | if (cpu->value->has_props && cpu->value->props->has_node_id && |
162 | cpu->value->props->node_id == i) { |
163 | monitor_printf(mon, " %" PRIi64, cpu->value->CPU); |
164 | } |
165 | } |
166 | monitor_printf(mon, "\n" ); |
167 | monitor_printf(mon, "node %d size: %" PRId64 " MB\n" , i, |
168 | node_mem[i].node_mem >> 20); |
169 | monitor_printf(mon, "node %d plugged: %" PRId64 " MB\n" , i, |
170 | node_mem[i].node_plugged_mem >> 20); |
171 | } |
172 | qapi_free_CpuInfoList(cpu_list); |
173 | g_free(node_mem); |
174 | } |
175 | |