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