1
2
3
4
5
6
7
8
9
10
11
12#include "qemu/osdep.h"
13#include "libqtest.h"
14
15static char *make_cli(const char *generic_cli, const char *test_cli)
16{
17 return g_strdup_printf("%s %s", generic_cli ? generic_cli : "", test_cli);
18}
19
20static void test_mon_explicit(const void *data)
21{
22 char *s;
23 char *cli;
24
25 cli = make_cli(data, "-smp 8 "
26 "-numa node,nodeid=0,cpus=0-3 "
27 "-numa node,nodeid=1,cpus=4-7 ");
28 qtest_start(cli);
29
30 s = hmp("info numa");
31 g_assert(strstr(s, "node 0 cpus: 0 1 2 3"));
32 g_assert(strstr(s, "node 1 cpus: 4 5 6 7"));
33 g_free(s);
34
35 qtest_end();
36 g_free(cli);
37}
38
39static void test_mon_default(const void *data)
40{
41 char *s;
42 char *cli;
43
44 cli = make_cli(data, "-smp 8 -numa node -numa node");
45 qtest_start(cli);
46
47 s = hmp("info numa");
48 g_assert(strstr(s, "node 0 cpus: 0 2 4 6"));
49 g_assert(strstr(s, "node 1 cpus: 1 3 5 7"));
50 g_free(s);
51
52 qtest_end();
53 g_free(cli);
54}
55
56static void test_mon_partial(const void *data)
57{
58 char *s;
59 char *cli;
60
61 cli = make_cli(data, "-smp 8 "
62 "-numa node,nodeid=0,cpus=0-1 "
63 "-numa node,nodeid=1,cpus=4-5 ");
64 qtest_start(cli);
65
66 s = hmp("info numa");
67 g_assert(strstr(s, "node 0 cpus: 0 1 2 3 6 7"));
68 g_assert(strstr(s, "node 1 cpus: 4 5"));
69 g_free(s);
70
71 qtest_end();
72 g_free(cli);
73}
74
75static QList *get_cpus(QDict **resp)
76{
77 *resp = qmp("{ 'execute': 'query-cpus' }");
78 g_assert(*resp);
79 g_assert(qdict_haskey(*resp, "return"));
80 return qdict_get_qlist(*resp, "return");
81}
82
83static void test_query_cpus(const void *data)
84{
85 char *cli;
86 QDict *resp;
87 QList *cpus;
88 QObject *e;
89
90 cli = make_cli(data, "-smp 8 -numa node,cpus=0-3 -numa node,cpus=4-7");
91 qtest_start(cli);
92 cpus = get_cpus(&resp);
93 g_assert(cpus);
94
95 while ((e = qlist_pop(cpus))) {
96 QDict *cpu, *props;
97 int64_t cpu_idx, node;
98
99 cpu = qobject_to_qdict(e);
100 g_assert(qdict_haskey(cpu, "CPU"));
101 g_assert(qdict_haskey(cpu, "props"));
102
103 cpu_idx = qdict_get_int(cpu, "CPU");
104 props = qdict_get_qdict(cpu, "props");
105 g_assert(qdict_haskey(props, "node-id"));
106 node = qdict_get_int(props, "node-id");
107 if (cpu_idx >= 0 && cpu_idx < 4) {
108 g_assert_cmpint(node, ==, 0);
109 } else {
110 g_assert_cmpint(node, ==, 1);
111 }
112 qobject_decref(e);
113 }
114
115 QDECREF(resp);
116 qtest_end();
117 g_free(cli);
118}
119
120static void pc_numa_cpu(const void *data)
121{
122 char *cli;
123 QDict *resp;
124 QList *cpus;
125 QObject *e;
126
127 cli = make_cli(data, "-cpu pentium -smp 8,sockets=2,cores=2,threads=2 "
128 "-numa node,nodeid=0 -numa node,nodeid=1 "
129 "-numa cpu,node-id=1,socket-id=0 "
130 "-numa cpu,node-id=0,socket-id=1,core-id=0 "
131 "-numa cpu,node-id=0,socket-id=1,core-id=1,thread-id=0 "
132 "-numa cpu,node-id=1,socket-id=1,core-id=1,thread-id=1");
133 qtest_start(cli);
134 cpus = get_cpus(&resp);
135 g_assert(cpus);
136
137 while ((e = qlist_pop(cpus))) {
138 QDict *cpu, *props;
139 int64_t socket, core, thread, node;
140
141 cpu = qobject_to_qdict(e);
142 g_assert(qdict_haskey(cpu, "props"));
143 props = qdict_get_qdict(cpu, "props");
144
145 g_assert(qdict_haskey(props, "node-id"));
146 node = qdict_get_int(props, "node-id");
147 g_assert(qdict_haskey(props, "socket-id"));
148 socket = qdict_get_int(props, "socket-id");
149 g_assert(qdict_haskey(props, "core-id"));
150 core = qdict_get_int(props, "core-id");
151 g_assert(qdict_haskey(props, "thread-id"));
152 thread = qdict_get_int(props, "thread-id");
153
154 if (socket == 0) {
155 g_assert_cmpint(node, ==, 1);
156 } else if (socket == 1 && core == 0) {
157 g_assert_cmpint(node, ==, 0);
158 } else if (socket == 1 && core == 1 && thread == 0) {
159 g_assert_cmpint(node, ==, 0);
160 } else if (socket == 1 && core == 1 && thread == 1) {
161 g_assert_cmpint(node, ==, 1);
162 } else {
163 g_assert(false);
164 }
165 qobject_decref(e);
166 }
167
168 QDECREF(resp);
169 qtest_end();
170 g_free(cli);
171}
172
173static void spapr_numa_cpu(const void *data)
174{
175 char *cli;
176 QDict *resp;
177 QList *cpus;
178 QObject *e;
179
180 cli = make_cli(data, "-smp 4,cores=4 "
181 "-numa node,nodeid=0 -numa node,nodeid=1 "
182 "-numa cpu,node-id=0,core-id=0 "
183 "-numa cpu,node-id=0,core-id=1 "
184 "-numa cpu,node-id=0,core-id=2 "
185 "-numa cpu,node-id=1,core-id=3");
186 qtest_start(cli);
187 cpus = get_cpus(&resp);
188 g_assert(cpus);
189
190 while ((e = qlist_pop(cpus))) {
191 QDict *cpu, *props;
192 int64_t core, node;
193
194 cpu = qobject_to_qdict(e);
195 g_assert(qdict_haskey(cpu, "props"));
196 props = qdict_get_qdict(cpu, "props");
197
198 g_assert(qdict_haskey(props, "node-id"));
199 node = qdict_get_int(props, "node-id");
200 g_assert(qdict_haskey(props, "core-id"));
201 core = qdict_get_int(props, "core-id");
202
203 if (core >= 0 && core < 3) {
204 g_assert_cmpint(node, ==, 0);
205 } else if (core == 3) {
206 g_assert_cmpint(node, ==, 1);
207 } else {
208 g_assert(false);
209 }
210 qobject_decref(e);
211 }
212
213 QDECREF(resp);
214 qtest_end();
215 g_free(cli);
216}
217
218static void aarch64_numa_cpu(const void *data)
219{
220 char *cli;
221 QDict *resp;
222 QList *cpus;
223 QObject *e;
224
225 cli = make_cli(data, "-smp 2 "
226 "-numa node,nodeid=0 -numa node,nodeid=1 "
227 "-numa cpu,node-id=1,thread-id=0 "
228 "-numa cpu,node-id=0,thread-id=1");
229 qtest_start(cli);
230 cpus = get_cpus(&resp);
231 g_assert(cpus);
232
233 while ((e = qlist_pop(cpus))) {
234 QDict *cpu, *props;
235 int64_t thread, node;
236
237 cpu = qobject_to_qdict(e);
238 g_assert(qdict_haskey(cpu, "props"));
239 props = qdict_get_qdict(cpu, "props");
240
241 g_assert(qdict_haskey(props, "node-id"));
242 node = qdict_get_int(props, "node-id");
243 g_assert(qdict_haskey(props, "thread-id"));
244 thread = qdict_get_int(props, "thread-id");
245
246 if (thread == 0) {
247 g_assert_cmpint(node, ==, 1);
248 } else if (thread == 1) {
249 g_assert_cmpint(node, ==, 0);
250 } else {
251 g_assert(false);
252 }
253 qobject_decref(e);
254 }
255
256 QDECREF(resp);
257 qtest_end();
258 g_free(cli);
259}
260
261int main(int argc, char **argv)
262{
263 const char *args = NULL;
264 const char *arch = qtest_get_arch();
265
266 if (strcmp(arch, "aarch64") == 0) {
267 args = "-machine virt";
268 }
269
270 g_test_init(&argc, &argv, NULL);
271
272 qtest_add_data_func("/numa/mon/default", args, test_mon_default);
273 qtest_add_data_func("/numa/mon/cpus/explicit", args, test_mon_explicit);
274 qtest_add_data_func("/numa/mon/cpus/partial", args, test_mon_partial);
275 qtest_add_data_func("/numa/qmp/cpus/query-cpus", args, test_query_cpus);
276
277 if (!strcmp(arch, "i386") || !strcmp(arch, "x86_64")) {
278 qtest_add_data_func("/numa/pc/cpu/explicit", args, pc_numa_cpu);
279 }
280
281 if (!strcmp(arch, "ppc64")) {
282 qtest_add_data_func("/numa/spapr/cpu/explicit", args, spapr_numa_cpu);
283 }
284
285 if (!strcmp(arch, "aarch64")) {
286 qtest_add_data_func("/numa/aarch64/cpu/explicit", args,
287 aarch64_numa_cpu);
288 }
289
290 return g_test_run();
291}
292