]>
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" | |
a2ce7dbd | 13 | #include "libqos/libqtest.h" |
452fcdbc | 14 | #include "qapi/qmp/qdict.h" |
47e6b297 | 15 | #include "qapi/qmp/qlist.h" |
63baf8bf | 16 | |
786ed5c4 | 17 | static char *make_cli(const GString *generic_cli, const char *test_cli) |
63baf8bf | 18 | { |
786ed5c4 | 19 | return g_strdup_printf("%s %s", generic_cli->str, test_cli); |
63baf8bf IM |
20 | } |
21 | ||
63baf8bf IM |
22 | static void test_mon_explicit(const void *data) |
23 | { | |
3d5e7087 | 24 | QTestState *qts; |
786ed5c4 IM |
25 | g_autofree char *s = NULL; |
26 | g_autofree char *cli = NULL; | |
63baf8bf | 27 | |
9584b564 IM |
28 | cli = make_cli(data, "-smp 8 -numa node,nodeid=0,memdev=ram,cpus=0-3 " |
29 | "-numa node,nodeid=1,cpus=4-7"); | |
3d5e7087 | 30 | qts = qtest_init(cli); |
63baf8bf | 31 | |
3d5e7087 | 32 | s = qtest_hmp(qts, "info numa"); |
63baf8bf IM |
33 | g_assert(strstr(s, "node 0 cpus: 0 1 2 3")); |
34 | g_assert(strstr(s, "node 1 cpus: 4 5 6 7")); | |
63baf8bf | 35 | |
3d5e7087 | 36 | qtest_quit(qts); |
63baf8bf IM |
37 | } |
38 | ||
9584b564 | 39 | static void test_def_cpu_split(const void *data) |
63baf8bf | 40 | { |
3d5e7087 | 41 | QTestState *qts; |
786ed5c4 IM |
42 | g_autofree char *s = NULL; |
43 | g_autofree char *cli = NULL; | |
63baf8bf | 44 | |
9584b564 | 45 | cli = make_cli(data, "-smp 8 -numa node,memdev=ram -numa node"); |
3d5e7087 | 46 | qts = qtest_init(cli); |
63baf8bf | 47 | |
3d5e7087 | 48 | s = qtest_hmp(qts, "info numa"); |
63baf8bf IM |
49 | g_assert(strstr(s, "node 0 cpus: 0 2 4 6")); |
50 | g_assert(strstr(s, "node 1 cpus: 1 3 5 7")); | |
63baf8bf | 51 | |
3d5e7087 | 52 | qtest_quit(qts); |
63baf8bf IM |
53 | } |
54 | ||
55 | static void test_mon_partial(const void *data) | |
56 | { | |
3d5e7087 | 57 | QTestState *qts; |
786ed5c4 IM |
58 | g_autofree char *s = NULL; |
59 | g_autofree char *cli = NULL; | |
63baf8bf IM |
60 | |
61 | cli = make_cli(data, "-smp 8 " | |
9584b564 | 62 | "-numa node,nodeid=0,memdev=ram,cpus=0-1 " |
63baf8bf | 63 | "-numa node,nodeid=1,cpus=4-5 "); |
3d5e7087 | 64 | qts = qtest_init(cli); |
63baf8bf | 65 | |
3d5e7087 | 66 | s = qtest_hmp(qts, "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")); | |
63baf8bf | 69 | |
3d5e7087 | 70 | qtest_quit(qts); |
63baf8bf IM |
71 | } |
72 | ||
3d5e7087 | 73 | static QList *get_cpus(QTestState *qts, QDict **resp) |
6accfb78 | 74 | { |
3d5e7087 | 75 | *resp = qtest_qmp(qts, "{ 'execute': 'query-cpus' }"); |
6accfb78 IM |
76 | g_assert(*resp); |
77 | g_assert(qdict_haskey(*resp, "return")); | |
5e39d89d | 78 | return qdict_get_qlist(*resp, "return"); |
6accfb78 IM |
79 | } |
80 | ||
81 | static void test_query_cpus(const void *data) | |
82 | { | |
6accfb78 IM |
83 | QDict *resp; |
84 | QList *cpus; | |
5e39d89d | 85 | QObject *e; |
3d5e7087 | 86 | QTestState *qts; |
786ed5c4 | 87 | g_autofree char *cli = NULL; |
6accfb78 | 88 | |
9584b564 IM |
89 | cli = make_cli(data, "-smp 8 -numa node,memdev=ram,cpus=0-3 " |
90 | "-numa node,cpus=4-7"); | |
3d5e7087 TH |
91 | qts = qtest_init(cli); |
92 | cpus = get_cpus(qts, &resp); | |
6accfb78 IM |
93 | g_assert(cpus); |
94 | ||
95 | while ((e = qlist_pop(cpus))) { | |
96 | QDict *cpu, *props; | |
97 | int64_t cpu_idx, node; | |
98 | ||
7dc847eb | 99 | cpu = qobject_to(QDict, e); |
6accfb78 IM |
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 | } | |
cb3e7f08 | 112 | qobject_unref(e); |
6accfb78 IM |
113 | } |
114 | ||
cb3e7f08 | 115 | qobject_unref(resp); |
3d5e7087 | 116 | qtest_quit(qts); |
6accfb78 IM |
117 | } |
118 | ||
2941020a IM |
119 | static void pc_numa_cpu(const void *data) |
120 | { | |
2941020a IM |
121 | QDict *resp; |
122 | QList *cpus; | |
5e39d89d | 123 | QObject *e; |
3d5e7087 | 124 | QTestState *qts; |
786ed5c4 | 125 | g_autofree char *cli = NULL; |
2941020a IM |
126 | |
127 | cli = make_cli(data, "-cpu pentium -smp 8,sockets=2,cores=2,threads=2 " | |
9584b564 | 128 | "-numa node,nodeid=0,memdev=ram -numa node,nodeid=1 " |
2941020a IM |
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"); | |
3d5e7087 TH |
133 | qts = qtest_init(cli); |
134 | cpus = get_cpus(qts, &resp); | |
2941020a IM |
135 | g_assert(cpus); |
136 | ||
137 | while ((e = qlist_pop(cpus))) { | |
138 | QDict *cpu, *props; | |
139 | int64_t socket, core, thread, node; | |
140 | ||
7dc847eb | 141 | cpu = qobject_to(QDict, e); |
2941020a IM |
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 | } | |
cb3e7f08 | 165 | qobject_unref(e); |
2941020a IM |
166 | } |
167 | ||
cb3e7f08 | 168 | qobject_unref(resp); |
3d5e7087 | 169 | qtest_quit(qts); |
2941020a IM |
170 | } |
171 | ||
172 | static void spapr_numa_cpu(const void *data) | |
173 | { | |
2941020a IM |
174 | QDict *resp; |
175 | QList *cpus; | |
5e39d89d | 176 | QObject *e; |
3d5e7087 | 177 | QTestState *qts; |
786ed5c4 | 178 | g_autofree char *cli = NULL; |
2941020a IM |
179 | |
180 | cli = make_cli(data, "-smp 4,cores=4 " | |
9584b564 | 181 | "-numa node,nodeid=0,memdev=ram -numa node,nodeid=1 " |
2941020a IM |
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"); | |
3d5e7087 TH |
186 | qts = qtest_init(cli); |
187 | cpus = get_cpus(qts, &resp); | |
2941020a IM |
188 | g_assert(cpus); |
189 | ||
190 | while ((e = qlist_pop(cpus))) { | |
191 | QDict *cpu, *props; | |
192 | int64_t core, node; | |
193 | ||
7dc847eb | 194 | cpu = qobject_to(QDict, e); |
2941020a IM |
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 | } | |
cb3e7f08 | 210 | qobject_unref(e); |
2941020a IM |
211 | } |
212 | ||
cb3e7f08 | 213 | qobject_unref(resp); |
3d5e7087 | 214 | qtest_quit(qts); |
2941020a IM |
215 | } |
216 | ||
217 | static void aarch64_numa_cpu(const void *data) | |
218 | { | |
2941020a IM |
219 | QDict *resp; |
220 | QList *cpus; | |
5e39d89d | 221 | QObject *e; |
3d5e7087 | 222 | QTestState *qts; |
786ed5c4 | 223 | g_autofree char *cli = NULL; |
2941020a IM |
224 | |
225 | cli = make_cli(data, "-smp 2 " | |
9584b564 | 226 | "-numa node,nodeid=0,memdev=ram -numa node,nodeid=1 " |
2941020a IM |
227 | "-numa cpu,node-id=1,thread-id=0 " |
228 | "-numa cpu,node-id=0,thread-id=1"); | |
3d5e7087 TH |
229 | qts = qtest_init(cli); |
230 | cpus = get_cpus(qts, &resp); | |
2941020a IM |
231 | g_assert(cpus); |
232 | ||
233 | while ((e = qlist_pop(cpus))) { | |
234 | QDict *cpu, *props; | |
235 | int64_t thread, node; | |
236 | ||
7dc847eb | 237 | cpu = qobject_to(QDict, e); |
2941020a IM |
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 | } | |
cb3e7f08 | 253 | qobject_unref(e); |
2941020a IM |
254 | } |
255 | ||
cb3e7f08 | 256 | qobject_unref(resp); |
3d5e7087 | 257 | qtest_quit(qts); |
2941020a IM |
258 | } |
259 | ||
c35665e1 IM |
260 | static void pc_dynamic_cpu_cfg(const void *data) |
261 | { | |
262 | QObject *e; | |
263 | QDict *resp; | |
264 | QList *cpus; | |
265 | QTestState *qs; | |
786ed5c4 | 266 | g_autofree char *cli = NULL; |
c35665e1 | 267 | |
786ed5c4 IM |
268 | cli = make_cli(data, "-nodefaults --preconfig -smp 2"); |
269 | qs = qtest_init(cli); | |
c35665e1 IM |
270 | |
271 | /* create 2 numa nodes */ | |
272 | g_assert(!qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
9584b564 | 273 | " 'arguments': { 'type': 'node', 'nodeid': 0, 'memdev': 'ram' } }"))); |
c35665e1 IM |
274 | g_assert(!qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," |
275 | " 'arguments': { 'type': 'node', 'nodeid': 1 } }"))); | |
276 | ||
277 | /* map 2 cpus in non default reverse order | |
278 | * i.e socket1->node0, socket0->node1 | |
279 | */ | |
280 | g_assert(!qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
281 | " 'arguments': { 'type': 'cpu', 'node-id': 0, 'socket-id': 1 } }"))); | |
282 | g_assert(!qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
283 | " 'arguments': { 'type': 'cpu', 'node-id': 1, 'socket-id': 0 } }"))); | |
284 | ||
285 | /* let machine initialization to complete and run */ | |
361ac948 | 286 | g_assert(!qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'x-exit-preconfig' }"))); |
c35665e1 IM |
287 | qtest_qmp_eventwait(qs, "RESUME"); |
288 | ||
289 | /* check that CPUs are mapped as expected */ | |
290 | resp = qtest_qmp(qs, "{ 'execute': 'query-hotpluggable-cpus'}"); | |
291 | g_assert(qdict_haskey(resp, "return")); | |
292 | cpus = qdict_get_qlist(resp, "return"); | |
293 | g_assert(cpus); | |
294 | while ((e = qlist_pop(cpus))) { | |
295 | const QDict *cpu, *props; | |
296 | int64_t socket, node; | |
297 | ||
298 | cpu = qobject_to(QDict, e); | |
299 | g_assert(qdict_haskey(cpu, "props")); | |
300 | props = qdict_get_qdict(cpu, "props"); | |
301 | ||
302 | g_assert(qdict_haskey(props, "node-id")); | |
303 | node = qdict_get_int(props, "node-id"); | |
304 | g_assert(qdict_haskey(props, "socket-id")); | |
305 | socket = qdict_get_int(props, "socket-id"); | |
306 | ||
307 | if (socket == 0) { | |
308 | g_assert_cmpint(node, ==, 1); | |
309 | } else if (socket == 1) { | |
310 | g_assert_cmpint(node, ==, 0); | |
311 | } else { | |
312 | g_assert(false); | |
313 | } | |
314 | qobject_unref(e); | |
315 | } | |
316 | qobject_unref(resp); | |
317 | ||
318 | qtest_quit(qs); | |
319 | } | |
320 | ||
d00817c9 TX |
321 | static void pc_hmat_build_cfg(const void *data) |
322 | { | |
786ed5c4 IM |
323 | QTestState *qs; |
324 | g_autofree char *cli = NULL; | |
325 | ||
326 | cli = make_cli(data, "-nodefaults --preconfig -machine hmat=on " | |
327 | "-smp 2,sockets=2 " | |
328 | "-m 128M,slots=2,maxmem=1G " | |
329 | "-object memory-backend-ram,size=64M,id=m0 " | |
330 | "-object memory-backend-ram,size=64M,id=m1 " | |
331 | "-numa node,nodeid=0,memdev=m0 " | |
332 | "-numa node,nodeid=1,memdev=m1,initiator=0 " | |
333 | "-numa cpu,node-id=0,socket-id=0 " | |
334 | "-numa cpu,node-id=0,socket-id=1"); | |
335 | qs = qtest_init(cli); | |
d00817c9 TX |
336 | |
337 | /* Fail: Initiator should be less than the number of nodes */ | |
338 | g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
339 | " 'arguments': { 'type': 'hmat-lb', 'initiator': 2, 'target': 0," | |
340 | " 'hierarchy': \"memory\", 'data-type': \"access-latency\" } }"))); | |
341 | ||
342 | /* Fail: Target should be less than the number of nodes */ | |
343 | g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
344 | " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 2," | |
345 | " 'hierarchy': \"memory\", 'data-type': \"access-latency\" } }"))); | |
346 | ||
347 | /* Fail: Initiator should contain cpu */ | |
348 | g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
349 | " 'arguments': { 'type': 'hmat-lb', 'initiator': 1, 'target': 0," | |
350 | " 'hierarchy': \"memory\", 'data-type': \"access-latency\" } }"))); | |
351 | ||
352 | /* Fail: Data-type mismatch */ | |
353 | g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
354 | " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0," | |
355 | " 'hierarchy': \"memory\", 'data-type': \"write-latency\"," | |
356 | " 'bandwidth': 524288000 } }"))); | |
357 | g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
358 | " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0," | |
359 | " 'hierarchy': \"memory\", 'data-type': \"read-bandwidth\"," | |
360 | " 'latency': 5 } }"))); | |
361 | ||
362 | /* Fail: Bandwidth should be 1MB (1048576) aligned */ | |
363 | g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
364 | " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0," | |
365 | " 'hierarchy': \"memory\", 'data-type': \"access-bandwidth\"," | |
366 | " 'bandwidth': 1048575 } }"))); | |
367 | ||
368 | /* Configuring HMAT bandwidth and latency details */ | |
369 | g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
370 | " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0," | |
371 | " 'hierarchy': \"memory\", 'data-type': \"access-latency\"," | |
372 | " 'latency': 1 } }"))); /* 1 ns */ | |
373 | g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
374 | " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0," | |
375 | " 'hierarchy': \"memory\", 'data-type': \"access-latency\"," | |
376 | " 'latency': 5 } }"))); /* Fail: Duplicate configuration */ | |
377 | g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
378 | " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0," | |
379 | " 'hierarchy': \"memory\", 'data-type': \"access-bandwidth\"," | |
380 | " 'bandwidth': 68717379584 } }"))); /* 65534 MB/s */ | |
381 | g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
382 | " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 1," | |
383 | " 'hierarchy': \"memory\", 'data-type': \"access-latency\"," | |
384 | " 'latency': 65534 } }"))); /* 65534 ns */ | |
385 | g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
386 | " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 1," | |
387 | " 'hierarchy': \"memory\", 'data-type': \"access-bandwidth\"," | |
388 | " 'bandwidth': 34358689792 } }"))); /* 32767 MB/s */ | |
389 | ||
390 | /* Fail: node_id should be less than the number of nodes */ | |
391 | g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
392 | " 'arguments': { 'type': 'hmat-cache', 'node-id': 2, 'size': 10240," | |
393 | " 'level': 1, 'associativity': \"direct\", 'policy': \"write-back\"," | |
394 | " 'line': 8 } }"))); | |
395 | ||
396 | /* Fail: level should be less than HMAT_LB_LEVELS (4) */ | |
397 | g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
398 | " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240," | |
399 | " 'level': 4, 'associativity': \"direct\", 'policy': \"write-back\"," | |
400 | " 'line': 8 } }"))); | |
401 | ||
402 | /* Fail: associativity option should be 'none', if level is 0 */ | |
403 | g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
404 | " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240," | |
405 | " 'level': 0, 'associativity': \"direct\", 'policy': \"none\"," | |
406 | " 'line': 0 } }"))); | |
407 | /* Fail: policy option should be 'none', if level is 0 */ | |
408 | g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
409 | " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240," | |
410 | " 'level': 0, 'associativity': \"none\", 'policy': \"write-back\"," | |
411 | " 'line': 0 } }"))); | |
412 | /* Fail: line option should be 0, if level is 0 */ | |
413 | g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
414 | " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240," | |
415 | " 'level': 0, 'associativity': \"none\", 'policy': \"none\"," | |
416 | " 'line': 8 } }"))); | |
417 | ||
418 | /* Configuring HMAT memory side cache attributes */ | |
419 | g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
420 | " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240," | |
421 | " 'level': 1, 'associativity': \"direct\", 'policy': \"write-back\"," | |
422 | " 'line': 8 } }"))); | |
423 | g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
424 | " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240," | |
425 | " 'level': 1, 'associativity': \"direct\", 'policy': \"write-back\"," | |
426 | " 'line': 8 } }"))); /* Fail: Duplicate configuration */ | |
427 | /* Fail: The size of level 2 size should be small than level 1 */ | |
428 | g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
429 | " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240," | |
430 | " 'level': 2, 'associativity': \"direct\", 'policy': \"write-back\"," | |
431 | " 'line': 8 } }"))); | |
432 | /* Fail: The size of level 0 size should be larger than level 1 */ | |
433 | g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
434 | " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240," | |
435 | " 'level': 0, 'associativity': \"direct\", 'policy': \"write-back\"," | |
436 | " 'line': 8 } }"))); | |
437 | g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
438 | " 'arguments': { 'type': 'hmat-cache', 'node-id': 1, 'size': 10240," | |
439 | " 'level': 1, 'associativity': \"direct\", 'policy': \"write-back\"," | |
440 | " 'line': 8 } }"))); | |
441 | ||
442 | /* let machine initialization to complete and run */ | |
443 | g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, | |
444 | "{ 'execute': 'x-exit-preconfig' }"))); | |
445 | qtest_qmp_eventwait(qs, "RESUME"); | |
446 | ||
447 | qtest_quit(qs); | |
448 | } | |
449 | ||
450 | static void pc_hmat_off_cfg(const void *data) | |
451 | { | |
786ed5c4 IM |
452 | QTestState *qs; |
453 | g_autofree char *cli = NULL; | |
454 | ||
455 | cli = make_cli(data, "-nodefaults --preconfig " | |
456 | "-smp 2,sockets=2 " | |
457 | "-m 128M,slots=2,maxmem=1G " | |
e43651ff | 458 | "-object memory-backend-ram,size=64M,id=m0,prealloc=y " |
786ed5c4 IM |
459 | "-object memory-backend-ram,size=64M,id=m1 " |
460 | "-numa node,nodeid=0,memdev=m0"); | |
461 | qs = qtest_init(cli); | |
d00817c9 TX |
462 | |
463 | /* | |
464 | * Fail: Enable HMAT with -machine hmat=on | |
465 | * before using any of hmat specific options | |
466 | */ | |
467 | g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
468 | " 'arguments': { 'type': 'node', 'nodeid': 1, 'memdev': \"m1\"," | |
469 | " 'initiator': 0 } }"))); | |
470 | g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
471 | " 'arguments': { 'type': 'node', 'nodeid': 1, 'memdev': \"m1\" } }"))); | |
472 | g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
473 | " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0," | |
474 | " 'hierarchy': \"memory\", 'data-type': \"access-latency\"," | |
475 | " 'latency': 1 } }"))); | |
476 | g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
477 | " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240," | |
478 | " 'level': 1, 'associativity': \"direct\", 'policy': \"write-back\"," | |
479 | " 'line': 8 } }"))); | |
480 | ||
481 | /* let machine initialization to complete and run */ | |
482 | g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, | |
483 | "{ 'execute': 'x-exit-preconfig' }"))); | |
484 | qtest_qmp_eventwait(qs, "RESUME"); | |
485 | ||
486 | qtest_quit(qs); | |
487 | } | |
488 | ||
489 | static void pc_hmat_erange_cfg(const void *data) | |
490 | { | |
786ed5c4 IM |
491 | QTestState *qs; |
492 | g_autofree char *cli = NULL; | |
493 | ||
494 | cli = make_cli(data, "-nodefaults --preconfig -machine hmat=on " | |
495 | "-smp 2,sockets=2 " | |
496 | "-m 128M,slots=2,maxmem=1G " | |
497 | "-object memory-backend-ram,size=64M,id=m0 " | |
498 | "-object memory-backend-ram,size=64M,id=m1 " | |
499 | "-numa node,nodeid=0,memdev=m0 " | |
500 | "-numa node,nodeid=1,memdev=m1,initiator=0 " | |
501 | "-numa cpu,node-id=0,socket-id=0 " | |
502 | "-numa cpu,node-id=0,socket-id=1"); | |
503 | qs = qtest_init(cli); | |
d00817c9 TX |
504 | |
505 | /* Can't store the compressed latency */ | |
506 | g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
507 | " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0," | |
508 | " 'hierarchy': \"memory\", 'data-type': \"access-latency\"," | |
509 | " 'latency': 1 } }"))); /* 1 ns */ | |
510 | g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
511 | " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 1," | |
512 | " 'hierarchy': \"memory\", 'data-type': \"access-latency\"," | |
513 | " 'latency': 65535 } }"))); /* 65535 ns */ | |
514 | ||
515 | /* Test the 0 input (bandwidth not provided) */ | |
516 | g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
517 | " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0," | |
518 | " 'hierarchy': \"memory\", 'data-type': \"access-bandwidth\"," | |
519 | " 'bandwidth': 0 } }"))); /* 0 MB/s */ | |
520 | /* Fail: bandwidth should be provided before memory side cache attributes */ | |
521 | g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
522 | " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240," | |
523 | " 'level': 1, 'associativity': \"direct\", 'policy': \"write-back\"," | |
524 | " 'line': 8 } }"))); | |
525 | ||
526 | /* Can't store the compressed bandwidth */ | |
527 | g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," | |
528 | " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 1," | |
529 | " 'hierarchy': \"memory\", 'data-type': \"access-bandwidth\"," | |
530 | " 'bandwidth': 68718428160 } }"))); /* 65535 MB/s */ | |
531 | ||
532 | /* let machine initialization to complete and run */ | |
533 | g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, | |
534 | "{ 'execute': 'x-exit-preconfig' }"))); | |
535 | qtest_qmp_eventwait(qs, "RESUME"); | |
536 | ||
537 | qtest_quit(qs); | |
538 | } | |
539 | ||
63baf8bf IM |
540 | int main(int argc, char **argv) |
541 | { | |
786ed5c4 | 542 | g_autoptr(GString) args = g_string_new(NULL); |
63baf8bf IM |
543 | const char *arch = qtest_get_arch(); |
544 | ||
9584b564 IM |
545 | if (g_str_equal(arch, "ppc64")) { |
546 | g_string_append(args, " -object memory-backend-ram,id=ram,size=512M"); | |
547 | } else { | |
548 | g_string_append(args, " -object memory-backend-ram,id=ram,size=128M"); | |
549 | } | |
550 | ||
786ed5c4 IM |
551 | if (g_str_equal(arch, "aarch64")) { |
552 | g_string_append(args, " -machine virt"); | |
63baf8bf IM |
553 | } |
554 | ||
555 | g_test_init(&argc, &argv, NULL); | |
556 | ||
9584b564 | 557 | qtest_add_data_func("/numa/mon/cpus/default", args, test_def_cpu_split); |
63baf8bf IM |
558 | qtest_add_data_func("/numa/mon/cpus/explicit", args, test_mon_explicit); |
559 | qtest_add_data_func("/numa/mon/cpus/partial", args, test_mon_partial); | |
6accfb78 | 560 | qtest_add_data_func("/numa/qmp/cpus/query-cpus", args, test_query_cpus); |
63baf8bf | 561 | |
2941020a IM |
562 | if (!strcmp(arch, "i386") || !strcmp(arch, "x86_64")) { |
563 | qtest_add_data_func("/numa/pc/cpu/explicit", args, pc_numa_cpu); | |
c35665e1 | 564 | qtest_add_data_func("/numa/pc/dynamic/cpu", args, pc_dynamic_cpu_cfg); |
d00817c9 TX |
565 | qtest_add_data_func("/numa/pc/hmat/build", args, pc_hmat_build_cfg); |
566 | qtest_add_data_func("/numa/pc/hmat/off", args, pc_hmat_off_cfg); | |
567 | qtest_add_data_func("/numa/pc/hmat/erange", args, pc_hmat_erange_cfg); | |
2941020a IM |
568 | } |
569 | ||
570 | if (!strcmp(arch, "ppc64")) { | |
571 | qtest_add_data_func("/numa/spapr/cpu/explicit", args, spapr_numa_cpu); | |
572 | } | |
573 | ||
574 | if (!strcmp(arch, "aarch64")) { | |
575 | qtest_add_data_func("/numa/aarch64/cpu/explicit", args, | |
576 | aarch64_numa_cpu); | |
577 | } | |
578 | ||
63baf8bf IM |
579 | return g_test_run(); |
580 | } |