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 "libqos/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 smp.cpus=2 " 227 "-numa node,nodeid=0,memdev=ram -numa node,nodeid=1 " 228 "-numa cpu,node-id=1,thread-id=0 " 229 "-numa cpu,node-id=0,thread-id=1"); 230 qts = qtest_init(cli); 231 cpus = get_cpus(qts, &resp); 232 g_assert(cpus); 233 234 while ((e = qlist_pop(cpus))) { 235 QDict *cpu, *props; 236 int64_t thread, node; 237 238 cpu = qobject_to(QDict, e); 239 g_assert(qdict_haskey(cpu, "props")); 240 props = qdict_get_qdict(cpu, "props"); 241 242 g_assert(qdict_haskey(props, "node-id")); 243 node = qdict_get_int(props, "node-id"); 244 g_assert(qdict_haskey(props, "thread-id")); 245 thread = qdict_get_int(props, "thread-id"); 246 247 if (thread == 0) { 248 g_assert_cmpint(node, ==, 1); 249 } else if (thread == 1) { 250 g_assert_cmpint(node, ==, 0); 251 } else { 252 g_assert(false); 253 } 254 qobject_unref(e); 255 } 256 257 qobject_unref(resp); 258 qtest_quit(qts); 259 } 260 261 static void pc_dynamic_cpu_cfg(const void *data) 262 { 263 QObject *e; 264 QDict *resp; 265 QList *cpus; 266 QTestState *qs; 267 g_autofree char *cli = NULL; 268 269 cli = make_cli(data, "-nodefaults --preconfig " 270 "-machine smp.cpus=2,smp.sockets=2"); 271 qs = qtest_init(cli); 272 273 /* create 2 numa nodes */ 274 g_assert(!qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 275 " 'arguments': { 'type': 'node', 'nodeid': 0, 'memdev': 'ram' } }"))); 276 g_assert(!qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 277 " 'arguments': { 'type': 'node', 'nodeid': 1 } }"))); 278 279 /* map 2 cpus in non default reverse order 280 * i.e socket1->node0, socket0->node1 281 */ 282 g_assert(!qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 283 " 'arguments': { 'type': 'cpu', 'node-id': 0, 'socket-id': 1 } }"))); 284 g_assert(!qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 285 " 'arguments': { 'type': 'cpu', 'node-id': 1, 'socket-id': 0 } }"))); 286 287 /* let machine initialization to complete and run */ 288 g_assert(!qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'x-exit-preconfig' }"))); 289 qtest_qmp_eventwait(qs, "RESUME"); 290 291 /* check that CPUs are mapped as expected */ 292 resp = qtest_qmp(qs, "{ 'execute': 'query-hotpluggable-cpus'}"); 293 g_assert(qdict_haskey(resp, "return")); 294 cpus = qdict_get_qlist(resp, "return"); 295 g_assert(cpus); 296 while ((e = qlist_pop(cpus))) { 297 const QDict *cpu, *props; 298 int64_t socket, node; 299 300 cpu = qobject_to(QDict, e); 301 g_assert(qdict_haskey(cpu, "props")); 302 props = qdict_get_qdict(cpu, "props"); 303 304 g_assert(qdict_haskey(props, "node-id")); 305 node = qdict_get_int(props, "node-id"); 306 g_assert(qdict_haskey(props, "socket-id")); 307 socket = qdict_get_int(props, "socket-id"); 308 309 if (socket == 0) { 310 g_assert_cmpint(node, ==, 1); 311 } else if (socket == 1) { 312 g_assert_cmpint(node, ==, 0); 313 } else { 314 g_assert(false); 315 } 316 qobject_unref(e); 317 } 318 qobject_unref(resp); 319 320 qtest_quit(qs); 321 } 322 323 static void pc_hmat_build_cfg(const void *data) 324 { 325 QTestState *qs; 326 g_autofree char *cli = NULL; 327 328 cli = make_cli(data, "-nodefaults --preconfig -machine hmat=on " 329 "-machine smp.cpus=2,smp.sockets=2 " 330 "-m 128M,slots=2,maxmem=1G " 331 "-object memory-backend-ram,size=64M,id=m0 " 332 "-object memory-backend-ram,size=64M,id=m1 " 333 "-numa node,nodeid=0,memdev=m0 " 334 "-numa node,nodeid=1,memdev=m1,initiator=0 " 335 "-numa cpu,node-id=0,socket-id=0 " 336 "-numa cpu,node-id=0,socket-id=1"); 337 qs = qtest_init(cli); 338 339 /* Fail: Initiator should be less than the number of nodes */ 340 g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 341 " 'arguments': { 'type': 'hmat-lb', 'initiator': 2, 'target': 0," 342 " 'hierarchy': \"memory\", 'data-type': \"access-latency\" } }"))); 343 344 /* Fail: Target should be less than the number of nodes */ 345 g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 346 " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 2," 347 " 'hierarchy': \"memory\", 'data-type': \"access-latency\" } }"))); 348 349 /* Fail: Initiator should contain cpu */ 350 g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 351 " 'arguments': { 'type': 'hmat-lb', 'initiator': 1, 'target': 0," 352 " 'hierarchy': \"memory\", 'data-type': \"access-latency\" } }"))); 353 354 /* Fail: Data-type mismatch */ 355 g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 356 " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0," 357 " 'hierarchy': \"memory\", 'data-type': \"write-latency\"," 358 " 'bandwidth': 524288000 } }"))); 359 g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 360 " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0," 361 " 'hierarchy': \"memory\", 'data-type': \"read-bandwidth\"," 362 " 'latency': 5 } }"))); 363 364 /* Fail: Bandwidth should be 1MB (1048576) aligned */ 365 g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 366 " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0," 367 " 'hierarchy': \"memory\", 'data-type': \"access-bandwidth\"," 368 " 'bandwidth': 1048575 } }"))); 369 370 /* Configuring HMAT bandwidth and latency details */ 371 g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 372 " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0," 373 " 'hierarchy': \"memory\", 'data-type': \"access-latency\"," 374 " 'latency': 1 } }"))); /* 1 ns */ 375 g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 376 " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0," 377 " 'hierarchy': \"memory\", 'data-type': \"access-latency\"," 378 " 'latency': 5 } }"))); /* Fail: Duplicate configuration */ 379 g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 380 " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0," 381 " 'hierarchy': \"memory\", 'data-type': \"access-bandwidth\"," 382 " 'bandwidth': 68717379584 } }"))); /* 65534 MB/s */ 383 g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 384 " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 1," 385 " 'hierarchy': \"memory\", 'data-type': \"access-latency\"," 386 " 'latency': 65534 } }"))); /* 65534 ns */ 387 g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 388 " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 1," 389 " 'hierarchy': \"memory\", 'data-type': \"access-bandwidth\"," 390 " 'bandwidth': 34358689792 } }"))); /* 32767 MB/s */ 391 392 /* Fail: node_id should be less than the number of nodes */ 393 g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 394 " 'arguments': { 'type': 'hmat-cache', 'node-id': 2, 'size': 10240," 395 " 'level': 1, 'associativity': \"direct\", 'policy': \"write-back\"," 396 " 'line': 8 } }"))); 397 398 /* Fail: level should be less than HMAT_LB_LEVELS (4) */ 399 g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 400 " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240," 401 " 'level': 4, 'associativity': \"direct\", 'policy': \"write-back\"," 402 " 'line': 8 } }"))); 403 404 /* Fail: associativity option should be 'none', if level is 0 */ 405 g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 406 " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240," 407 " 'level': 0, 'associativity': \"direct\", 'policy': \"none\"," 408 " 'line': 0 } }"))); 409 /* Fail: policy option should be 'none', if level is 0 */ 410 g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 411 " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240," 412 " 'level': 0, 'associativity': \"none\", 'policy': \"write-back\"," 413 " 'line': 0 } }"))); 414 /* Fail: line option should be 0, if level is 0 */ 415 g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 416 " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240," 417 " 'level': 0, 'associativity': \"none\", 'policy': \"none\"," 418 " 'line': 8 } }"))); 419 420 /* Configuring HMAT memory side cache attributes */ 421 g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 422 " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240," 423 " 'level': 1, 'associativity': \"direct\", 'policy': \"write-back\"," 424 " 'line': 8 } }"))); 425 g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 426 " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240," 427 " 'level': 1, 'associativity': \"direct\", 'policy': \"write-back\"," 428 " 'line': 8 } }"))); /* Fail: Duplicate configuration */ 429 /* Fail: The size of level 2 size should be small than level 1 */ 430 g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 431 " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240," 432 " 'level': 2, 'associativity': \"direct\", 'policy': \"write-back\"," 433 " 'line': 8 } }"))); 434 /* Fail: The size of level 0 size should be larger than level 1 */ 435 g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 436 " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240," 437 " 'level': 0, 'associativity': \"direct\", 'policy': \"write-back\"," 438 " 'line': 8 } }"))); 439 g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 440 " 'arguments': { 'type': 'hmat-cache', 'node-id': 1, 'size': 10240," 441 " 'level': 1, 'associativity': \"direct\", 'policy': \"write-back\"," 442 " 'line': 8 } }"))); 443 444 /* let machine initialization to complete and run */ 445 g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, 446 "{ 'execute': 'x-exit-preconfig' }"))); 447 qtest_qmp_eventwait(qs, "RESUME"); 448 449 qtest_quit(qs); 450 } 451 452 static void pc_hmat_off_cfg(const void *data) 453 { 454 QTestState *qs; 455 g_autofree char *cli = NULL; 456 457 cli = make_cli(data, "-nodefaults --preconfig " 458 "-machine smp.cpus=2,smp.sockets=2 " 459 "-m 128M,slots=2,maxmem=1G " 460 "-object memory-backend-ram,size=64M,id=m0,prealloc=y " 461 "-object memory-backend-ram,size=64M,id=m1 " 462 "-numa node,nodeid=0,memdev=m0"); 463 qs = qtest_init(cli); 464 465 /* 466 * Fail: Enable HMAT with -machine hmat=on 467 * before using any of hmat specific options 468 */ 469 g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 470 " 'arguments': { 'type': 'node', 'nodeid': 1, 'memdev': \"m1\"," 471 " 'initiator': 0 } }"))); 472 g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 473 " 'arguments': { 'type': 'node', 'nodeid': 1, 'memdev': \"m1\" } }"))); 474 g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 475 " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0," 476 " 'hierarchy': \"memory\", 'data-type': \"access-latency\"," 477 " 'latency': 1 } }"))); 478 g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 479 " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240," 480 " 'level': 1, 'associativity': \"direct\", 'policy': \"write-back\"," 481 " 'line': 8 } }"))); 482 483 /* let machine initialization to complete and run */ 484 g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, 485 "{ 'execute': 'x-exit-preconfig' }"))); 486 qtest_qmp_eventwait(qs, "RESUME"); 487 488 qtest_quit(qs); 489 } 490 491 static void pc_hmat_erange_cfg(const void *data) 492 { 493 QTestState *qs; 494 g_autofree char *cli = NULL; 495 496 cli = make_cli(data, "-nodefaults --preconfig -machine hmat=on " 497 "-machine smp.cpus=2,smp.sockets=2 " 498 "-m 128M,slots=2,maxmem=1G " 499 "-object memory-backend-ram,size=64M,id=m0 " 500 "-object memory-backend-ram,size=64M,id=m1 " 501 "-numa node,nodeid=0,memdev=m0 " 502 "-numa node,nodeid=1,memdev=m1,initiator=0 " 503 "-numa cpu,node-id=0,socket-id=0 " 504 "-numa cpu,node-id=0,socket-id=1"); 505 qs = qtest_init(cli); 506 507 /* Can't store the compressed latency */ 508 g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 509 " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0," 510 " 'hierarchy': \"memory\", 'data-type': \"access-latency\"," 511 " 'latency': 1 } }"))); /* 1 ns */ 512 g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 513 " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 1," 514 " 'hierarchy': \"memory\", 'data-type': \"access-latency\"," 515 " 'latency': 65535 } }"))); /* 65535 ns */ 516 517 /* Test the 0 input (bandwidth not provided) */ 518 g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 519 " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0," 520 " 'hierarchy': \"memory\", 'data-type': \"access-bandwidth\"," 521 " 'bandwidth': 0 } }"))); /* 0 MB/s */ 522 /* Fail: bandwidth should be provided before memory side cache attributes */ 523 g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 524 " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240," 525 " 'level': 1, 'associativity': \"direct\", 'policy': \"write-back\"," 526 " 'line': 8 } }"))); 527 528 /* Can't store the compressed bandwidth */ 529 g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," 530 " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 1," 531 " 'hierarchy': \"memory\", 'data-type': \"access-bandwidth\"," 532 " 'bandwidth': 68718428160 } }"))); /* 65535 MB/s */ 533 534 /* let machine initialization to complete and run */ 535 g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, 536 "{ 'execute': 'x-exit-preconfig' }"))); 537 qtest_qmp_eventwait(qs, "RESUME"); 538 539 qtest_quit(qs); 540 } 541 542 int main(int argc, char **argv) 543 { 544 g_autoptr(GString) args = g_string_new(NULL); 545 const char *arch = qtest_get_arch(); 546 547 if (g_str_equal(arch, "ppc64")) { 548 g_string_append(args, " -object memory-backend-ram,id=ram,size=512M"); 549 } else { 550 g_string_append(args, " -object memory-backend-ram,id=ram,size=128M"); 551 } 552 553 if (g_str_equal(arch, "aarch64")) { 554 g_string_append(args, " -machine virt"); 555 } 556 557 g_test_init(&argc, &argv, NULL); 558 559 qtest_add_data_func("/numa/mon/cpus/default", args, test_def_cpu_split); 560 qtest_add_data_func("/numa/mon/cpus/explicit", args, test_mon_explicit); 561 qtest_add_data_func("/numa/mon/cpus/partial", args, test_mon_partial); 562 qtest_add_data_func("/numa/qmp/cpus/query-cpus", args, test_query_cpus); 563 564 if (!strcmp(arch, "i386") || !strcmp(arch, "x86_64")) { 565 qtest_add_data_func("/numa/pc/cpu/explicit", args, pc_numa_cpu); 566 qtest_add_data_func("/numa/pc/dynamic/cpu", args, pc_dynamic_cpu_cfg); 567 qtest_add_data_func("/numa/pc/hmat/build", args, pc_hmat_build_cfg); 568 qtest_add_data_func("/numa/pc/hmat/off", args, pc_hmat_off_cfg); 569 qtest_add_data_func("/numa/pc/hmat/erange", args, pc_hmat_erange_cfg); 570 } 571 572 if (!strcmp(arch, "ppc64")) { 573 qtest_add_data_func("/numa/spapr/cpu/explicit", args, spapr_numa_cpu); 574 } 575 576 if (!strcmp(arch, "aarch64")) { 577 qtest_add_data_func("/numa/aarch64/cpu/explicit", args, 578 aarch64_numa_cpu); 579 } 580 581 return g_test_run(); 582 } 583