]>
Commit | Line | Data |
---|---|---|
63baf8bf IM |
1 | /* |
2 | * NUMA configuration test cases | |
3 | * | |
4 | * Copyright (c) 2017 Red Hat Inc. | |
5 | * Authors: | |
6 | * Igor Mammedov <[email protected]> | |
7 | * | |
8 | * This work is licensed under the terms of the GNU GPL, version 2 or later. | |
9 | * See the COPYING file in the top-level directory. | |
10 | */ | |
11 | ||
12 | #include "qemu/osdep.h" | |
13 | #include "libqtest.h" | |
14 | ||
15 | static 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 | ||
63baf8bf IM |
20 | static 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 | ||
e8fc894b | 30 | s = hmp("info numa"); |
63baf8bf IM |
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 | ||
39 | static 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 | ||
e8fc894b | 47 | s = hmp("info numa"); |
63baf8bf IM |
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 | ||
56 | static 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 | ||
e8fc894b | 66 | s = hmp("info numa"); |
63baf8bf IM |
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 | ||
6accfb78 IM |
75 | static QList *get_cpus(QDict **resp) |
76 | { | |
77 | *resp = qmp("{ 'execute': 'query-cpus' }"); | |
78 | g_assert(*resp); | |
79 | g_assert(qdict_haskey(*resp, "return")); | |
5e39d89d | 80 | return qdict_get_qlist(*resp, "return"); |
6accfb78 IM |
81 | } |
82 | ||
83 | static void test_query_cpus(const void *data) | |
84 | { | |
85 | char *cli; | |
86 | QDict *resp; | |
87 | QList *cpus; | |
5e39d89d | 88 | QObject *e; |
6accfb78 IM |
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 | } | |
5e39d89d | 112 | qobject_decref(e); |
6accfb78 IM |
113 | } |
114 | ||
115 | QDECREF(resp); | |
116 | qtest_end(); | |
117 | g_free(cli); | |
118 | } | |
119 | ||
2941020a IM |
120 | static void pc_numa_cpu(const void *data) |
121 | { | |
122 | char *cli; | |
123 | QDict *resp; | |
124 | QList *cpus; | |
5e39d89d | 125 | QObject *e; |
2941020a IM |
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 | } | |
5e39d89d | 165 | qobject_decref(e); |
2941020a IM |
166 | } |
167 | ||
168 | QDECREF(resp); | |
169 | qtest_end(); | |
170 | g_free(cli); | |
171 | } | |
172 | ||
173 | static void spapr_numa_cpu(const void *data) | |
174 | { | |
175 | char *cli; | |
176 | QDict *resp; | |
177 | QList *cpus; | |
5e39d89d | 178 | QObject *e; |
2941020a IM |
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 | } | |
5e39d89d | 210 | qobject_decref(e); |
2941020a IM |
211 | } |
212 | ||
213 | QDECREF(resp); | |
214 | qtest_end(); | |
215 | g_free(cli); | |
216 | } | |
217 | ||
218 | static void aarch64_numa_cpu(const void *data) | |
219 | { | |
220 | char *cli; | |
221 | QDict *resp; | |
222 | QList *cpus; | |
5e39d89d | 223 | QObject *e; |
2941020a IM |
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 | } | |
5e39d89d | 253 | qobject_decref(e); |
2941020a IM |
254 | } |
255 | ||
256 | QDECREF(resp); | |
257 | qtest_end(); | |
258 | g_free(cli); | |
259 | } | |
260 | ||
63baf8bf IM |
261 | int 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); | |
6accfb78 | 275 | qtest_add_data_func("/numa/qmp/cpus/query-cpus", args, test_query_cpus); |
63baf8bf | 276 | |
2941020a IM |
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 | ||
63baf8bf IM |
290 | return g_test_run(); |
291 | } |