qemu/tests/qtest/numa-test.c
<<
>>
Prefs
   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
  17static 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
  22static 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, "-smp 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
  39static 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, "-smp 8 -numa node,memdev=ram -numa node");
  46    qts = qtest_init(cli);
  47
  48    s = qtest_hmp(qts, "info numa");
  49    g_assert(strstr(s, "node 0 cpus: 0 2 4 6"));
  50    g_assert(strstr(s, "node 1 cpus: 1 3 5 7"));
  51
  52    qtest_quit(qts);
  53}
  54
  55static void test_mon_partial(const void *data)
  56{
  57    QTestState *qts;
  58    g_autofree char *s = NULL;
  59    g_autofree char *cli = NULL;
  60
  61    cli = make_cli(data, "-smp 8 "
  62                   "-numa node,nodeid=0,memdev=ram,cpus=0-1 "
  63                   "-numa node,nodeid=1,cpus=4-5 ");
  64    qts = qtest_init(cli);
  65
  66    s = qtest_hmp(qts, "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
  70    qtest_quit(qts);
  71}
  72
  73static QList *get_cpus(QTestState *qts, QDict **resp)
  74{
  75    *resp = qtest_qmp(qts, "{ 'execute': 'query-cpus-fast' }");
  76    g_assert(*resp);
  77    g_assert(qdict_haskey(*resp, "return"));
  78    return qdict_get_qlist(*resp, "return");
  79}
  80
  81static void test_query_cpus(const void *data)
  82{
  83    QDict *resp;
  84    QList *cpus;
  85    QObject *e;
  86    QTestState *qts;
  87    g_autofree char *cli = NULL;
  88
  89    cli = make_cli(data, "-smp 8 -numa node,memdev=ram,cpus=0-3 "
  90                         "-numa node,cpus=4-7");
  91    qts = qtest_init(cli);
  92    cpus = get_cpus(qts, &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-index"));
 101        g_assert(qdict_haskey(cpu, "props"));
 102
 103        cpu_idx = qdict_get_int(cpu, "cpu-index");
 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_unref(e);
 113    }
 114
 115    qobject_unref(resp);
 116    qtest_quit(qts);
 117}
 118
 119static void pc_numa_cpu(const void *data)
 120{
 121    QDict *resp;
 122    QList *cpus;
 123    QObject *e;
 124    QTestState *qts;
 125    g_autofree char *cli = NULL;
 126
 127    cli = make_cli(data, "-cpu pentium -smp 8,sockets=2,cores=2,threads=2 "
 128        "-numa node,nodeid=0,memdev=ram -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    qts = qtest_init(cli);
 134    cpus = get_cpus(qts, &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_unref(e);
 166    }
 167
 168    qobject_unref(resp);
 169    qtest_quit(qts);
 170}
 171
 172static void spapr_numa_cpu(const void *data)
 173{
 174    QDict *resp;
 175    QList *cpus;
 176    QObject *e;
 177    QTestState *qts;
 178    g_autofree char *cli = NULL;
 179
 180    cli = make_cli(data, "-smp 4,cores=4 "
 181        "-numa node,nodeid=0,memdev=ram -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    qts = qtest_init(cli);
 187    cpus = get_cpus(qts, &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_unref(e);
 211    }
 212
 213    qobject_unref(resp);
 214    qtest_quit(qts);
 215}
 216
 217static void aarch64_numa_cpu(const void *data)
 218{
 219    QDict *resp;
 220    QList *cpus;
 221    QObject *e;
 222    QTestState *qts;
 223    g_autofree char *cli = NULL;
 224
 225    cli = make_cli(data, "-smp 2 "
 226        "-numa node,nodeid=0,memdev=ram -numa node,nodeid=1 "
 227        "-numa cpu,node-id=1,thread-id=0 "
 228        "-numa cpu,node-id=0,thread-id=1");
 229    qts = qtest_init(cli);
 230    cpus = get_cpus(qts, &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_unref(e);
 254    }
 255
 256    qobject_unref(resp);
 257    qtest_quit(qts);
 258}
 259
 260static void pc_dynamic_cpu_cfg(const void *data)
 261{
 262    QObject *e;
 263    QDict *resp;
 264    QList *cpus;
 265    QTestState *qs;
 266    g_autofree char *cli = NULL;
 267
 268    cli = make_cli(data, "-nodefaults --preconfig -smp 2");
 269    qs = qtest_init(cli);
 270
 271    /* create 2 numa nodes */
 272    g_assert(!qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
 273        " 'arguments': { 'type': 'node', 'nodeid': 0, 'memdev': 'ram' } }")));
 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 */
 286    g_assert(!qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'x-exit-preconfig' }")));
 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
 321static void pc_hmat_build_cfg(const void *data)
 322{
 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);
 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
 450static void pc_hmat_off_cfg(const void *data)
 451{
 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 "
 458                         "-object memory-backend-ram,size=64M,id=m0,prealloc=y "
 459                         "-object memory-backend-ram,size=64M,id=m1 "
 460                         "-numa node,nodeid=0,memdev=m0");
 461    qs = qtest_init(cli);
 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
 489static void pc_hmat_erange_cfg(const void *data)
 490{
 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);
 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
 540int main(int argc, char **argv)
 541{
 542    g_autoptr(GString) args = g_string_new(NULL);
 543    const char *arch = qtest_get_arch();
 544
 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
 551    if (g_str_equal(arch, "aarch64")) {
 552        g_string_append(args, " -machine virt");
 553    }
 554
 555    g_test_init(&argc, &argv, NULL);
 556
 557    qtest_add_data_func("/numa/mon/cpus/default", args, test_def_cpu_split);
 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);
 560    qtest_add_data_func("/numa/qmp/cpus/query-cpus", args, test_query_cpus);
 561
 562    if (!strcmp(arch, "i386") || !strcmp(arch, "x86_64")) {
 563        qtest_add_data_func("/numa/pc/cpu/explicit", args, pc_numa_cpu);
 564        qtest_add_data_func("/numa/pc/dynamic/cpu", args, pc_dynamic_cpu_cfg);
 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);
 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
 579    return g_test_run();
 580}
 581