diff options
Diffstat (limited to 'tests')
-rwxr-xr-x | tests/acceptance/virtio_seg_max_adjust.py | 134 | ||||
-rw-r--r-- | tests/bios-tables-test.c | 44 | ||||
-rw-r--r-- | tests/data/acpi/pc/APIC.acpihmat | bin | 0 -> 128 bytes | |||
-rw-r--r-- | tests/data/acpi/pc/DSDT.acpihmat | bin | 0 -> 6455 bytes | |||
-rw-r--r-- | tests/data/acpi/pc/HMAT.acpihmat | bin | 0 -> 280 bytes | |||
-rw-r--r-- | tests/data/acpi/pc/SRAT.acpihmat | bin | 0 -> 280 bytes | |||
-rw-r--r-- | tests/data/acpi/q35/APIC.acpihmat | bin | 0 -> 128 bytes | |||
-rw-r--r-- | tests/data/acpi/q35/DSDT.acpihmat | bin | 0 -> 9203 bytes | |||
-rw-r--r-- | tests/data/acpi/q35/HMAT.acpihmat | bin | 0 -> 280 bytes | |||
-rw-r--r-- | tests/data/acpi/q35/SRAT.acpihmat | bin | 0 -> 280 bytes | |||
-rw-r--r-- | tests/iothread.c | 30 | ||||
-rw-r--r-- | tests/numa-test.c | 213 |
12 files changed, 421 insertions, 0 deletions
diff --git a/tests/acceptance/virtio_seg_max_adjust.py b/tests/acceptance/virtio_seg_max_adjust.py new file mode 100755 index 0000000000..5458573138 --- /dev/null +++ b/tests/acceptance/virtio_seg_max_adjust.py @@ -0,0 +1,134 @@ +#!/usr/bin/env python +# +# Test virtio-scsi and virtio-blk queue settings for all machine types +# +# Copyright (c) 2019 Virtuozzo International GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +import sys +import os +import re + +sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python')) +from qemu.machine import QEMUMachine +from avocado_qemu import Test + +#list of machine types and virtqueue properties to test +VIRTIO_SCSI_PROPS = {'seg_max_adjust': 'seg_max_adjust'} +VIRTIO_BLK_PROPS = {'seg_max_adjust': 'seg-max-adjust'} + +DEV_TYPES = {'virtio-scsi-pci': VIRTIO_SCSI_PROPS, + 'virtio-blk-pci': VIRTIO_BLK_PROPS} + +VM_DEV_PARAMS = {'virtio-scsi-pci': ['-device', 'virtio-scsi-pci,id=scsi0'], + 'virtio-blk-pci': ['-device', + 'virtio-blk-pci,id=scsi0,drive=drive0', + '-drive', + 'driver=null-co,id=drive0,if=none']} + + +class VirtioMaxSegSettingsCheck(Test): + @staticmethod + def make_pattern(props): + pattern_items = ['{0} = \w+'.format(prop) for prop in props] + return '|'.join(pattern_items) + + def query_virtqueue(self, vm, dev_type_name): + query_ok = False + error = None + props = None + + output = vm.command('human-monitor-command', + command_line = 'info qtree') + props_list = DEV_TYPES[dev_type_name].values(); + pattern = self.make_pattern(props_list) + res = re.findall(pattern, output) + + if len(res) != len(props_list): + props_list = set(props_list) + res = set(res) + not_found = props_list.difference(res) + not_found = ', '.join(not_found) + error = '({0}): The following properties not found: {1}'\ + .format(dev_type_name, not_found) + else: + query_ok = True + props = dict() + for prop in res: + p = prop.split(' = ') + props[p[0]] = p[1] + return query_ok, props, error + + def check_mt(self, mt, dev_type_name): + with QEMUMachine(self.qemu_bin) as vm: + vm.set_machine(mt["name"]) + for s in VM_DEV_PARAMS[dev_type_name]: + vm.add_args(s) + vm.launch() + query_ok, props, error = self.query_virtqueue(vm, dev_type_name) + + if not query_ok: + self.fail('machine type {0}: {1}'.format(mt['name'], error)) + + for prop_name, prop_val in props.items(): + expected_val = mt[prop_name] + self.assertEqual(expected_val, prop_val) + + @staticmethod + def seg_max_adjust_enabled(mt): + # machine types >= 5.0 should have seg_max_adjust = true + # others seg_max_adjust = false + mt = mt.split("-") + + # machine types with one line name and name like pc-x.x + if len(mt) <= 2: + return False + + # machine types like pc-<chip_name>-x.x[.x] + ver = mt[2] + ver = ver.split("."); + + # versions >= 5.0 goes with seg_max_adjust enabled + major = int(ver[0]) + + if major >= 5: + return True + return False + + def test_machine_types(self): + # collect all machine types except 'none', 'isapc', 'microvm' + with QEMUMachine(self.qemu_bin) as vm: + vm.launch() + machines = [m['name'] for m in vm.command('query-machines')] + vm.shutdown() + machines.remove('none') + machines.remove('isapc') + machines.remove('microvm') + + for dev_type in DEV_TYPES: + # create the list of machine types and their parameters. + mtypes = list() + for m in machines: + if self.seg_max_adjust_enabled(m): + enabled = 'true' + else: + enabled = 'false' + mtypes.append({'name': m, + DEV_TYPES[dev_type]['seg_max_adjust']: enabled}) + + # test each machine type for a device type + for mt in mtypes: + self.check_mt(mt, dev_type) diff --git a/tests/bios-tables-test.c b/tests/bios-tables-test.c index bc0ad594a1..f1ac2d7e96 100644 --- a/tests/bios-tables-test.c +++ b/tests/bios-tables-test.c @@ -947,6 +947,48 @@ static void test_acpi_virt_tcg_numamem(void) } +static void test_acpi_tcg_acpi_hmat(const char *machine) +{ + test_data data; + + memset(&data, 0, sizeof(data)); + data.machine = machine; + data.variant = ".acpihmat"; + test_acpi_one(" -machine hmat=on" + " -smp 2,sockets=2" + " -m 128M,slots=2,maxmem=1G" + " -object memory-backend-ram,size=64M,id=m0" + " -object memory-backend-ram,size=64M,id=m1" + " -numa node,nodeid=0,memdev=m0" + " -numa node,nodeid=1,memdev=m1,initiator=0" + " -numa cpu,node-id=0,socket-id=0" + " -numa cpu,node-id=0,socket-id=1" + " -numa hmat-lb,initiator=0,target=0,hierarchy=memory," + "data-type=access-latency,latency=1" + " -numa hmat-lb,initiator=0,target=0,hierarchy=memory," + "data-type=access-bandwidth,bandwidth=65534M" + " -numa hmat-lb,initiator=0,target=1,hierarchy=memory," + "data-type=access-latency,latency=65534" + " -numa hmat-lb,initiator=0,target=1,hierarchy=memory," + "data-type=access-bandwidth,bandwidth=32767M" + " -numa hmat-cache,node-id=0,size=10K,level=1," + "associativity=direct,policy=write-back,line=8" + " -numa hmat-cache,node-id=1,size=10K,level=1," + "associativity=direct,policy=write-back,line=8", + &data); + free_test_data(&data); +} + +static void test_acpi_q35_tcg_acpi_hmat(void) +{ + test_acpi_tcg_acpi_hmat(MACHINE_Q35); +} + +static void test_acpi_piix4_tcg_acpi_hmat(void) +{ + test_acpi_tcg_acpi_hmat(MACHINE_PC); +} + static void test_acpi_virt_tcg(void) { test_data data = { @@ -991,6 +1033,8 @@ int main(int argc, char *argv[]) qtest_add_func("acpi/q35/numamem", test_acpi_q35_tcg_numamem); qtest_add_func("acpi/piix4/dimmpxm", test_acpi_piix4_tcg_dimm_pxm); qtest_add_func("acpi/q35/dimmpxm", test_acpi_q35_tcg_dimm_pxm); + qtest_add_func("acpi/piix4/acpihmat", test_acpi_piix4_tcg_acpi_hmat); + qtest_add_func("acpi/q35/acpihmat", test_acpi_q35_tcg_acpi_hmat); } else if (strcmp(arch, "aarch64") == 0) { qtest_add_func("acpi/virt", test_acpi_virt_tcg); qtest_add_func("acpi/virt/numamem", test_acpi_virt_tcg_numamem); diff --git a/tests/data/acpi/pc/APIC.acpihmat b/tests/data/acpi/pc/APIC.acpihmat Binary files differnew file mode 100644 index 0000000000..a21f164699 --- /dev/null +++ b/tests/data/acpi/pc/APIC.acpihmat diff --git a/tests/data/acpi/pc/DSDT.acpihmat b/tests/data/acpi/pc/DSDT.acpihmat Binary files differnew file mode 100644 index 0000000000..ad890e09aa --- /dev/null +++ b/tests/data/acpi/pc/DSDT.acpihmat diff --git a/tests/data/acpi/pc/HMAT.acpihmat b/tests/data/acpi/pc/HMAT.acpihmat Binary files differnew file mode 100644 index 0000000000..c00f7ba6cd --- /dev/null +++ b/tests/data/acpi/pc/HMAT.acpihmat diff --git a/tests/data/acpi/pc/SRAT.acpihmat b/tests/data/acpi/pc/SRAT.acpihmat Binary files differnew file mode 100644 index 0000000000..1dcae90aec --- /dev/null +++ b/tests/data/acpi/pc/SRAT.acpihmat diff --git a/tests/data/acpi/q35/APIC.acpihmat b/tests/data/acpi/q35/APIC.acpihmat Binary files differnew file mode 100644 index 0000000000..a21f164699 --- /dev/null +++ b/tests/data/acpi/q35/APIC.acpihmat diff --git a/tests/data/acpi/q35/DSDT.acpihmat b/tests/data/acpi/q35/DSDT.acpihmat Binary files differnew file mode 100644 index 0000000000..30e3717b5b --- /dev/null +++ b/tests/data/acpi/q35/DSDT.acpihmat diff --git a/tests/data/acpi/q35/HMAT.acpihmat b/tests/data/acpi/q35/HMAT.acpihmat Binary files differnew file mode 100644 index 0000000000..c00f7ba6cd --- /dev/null +++ b/tests/data/acpi/q35/HMAT.acpihmat diff --git a/tests/data/acpi/q35/SRAT.acpihmat b/tests/data/acpi/q35/SRAT.acpihmat Binary files differnew file mode 100644 index 0000000000..1dcae90aec --- /dev/null +++ b/tests/data/acpi/q35/SRAT.acpihmat diff --git a/tests/iothread.c b/tests/iothread.c index 13c9fdcd8d..d3a2ee9a01 100644 --- a/tests/iothread.c +++ b/tests/iothread.c @@ -21,6 +21,8 @@ struct IOThread { AioContext *ctx; + GMainContext *worker_context; + GMainLoop *main_loop; QemuThread thread; QemuMutex init_done_lock; @@ -35,6 +37,17 @@ AioContext *qemu_get_current_aio_context(void) return my_iothread ? my_iothread->ctx : qemu_get_aio_context(); } +static void iothread_init_gcontext(IOThread *iothread) +{ + GSource *source; + + iothread->worker_context = g_main_context_new(); + source = aio_get_g_source(iothread_get_aio_context(iothread)); + g_source_attach(source, iothread->worker_context); + g_source_unref(source); + iothread->main_loop = g_main_loop_new(iothread->worker_context, TRUE); +} + static void *iothread_run(void *opaque) { IOThread *iothread = opaque; @@ -44,6 +57,20 @@ static void *iothread_run(void *opaque) my_iothread = iothread; qemu_mutex_lock(&iothread->init_done_lock); iothread->ctx = aio_context_new(&error_abort); + + /* + * We must connect the ctx to a GMainContext, because in older versions + * of glib the g_source_ref()/unref() functions are not threadsafe + * on sources without a context. + */ + iothread_init_gcontext(iothread); + + /* + * g_main_context_push_thread_default() must be called before anything + * in this new thread uses glib. + */ + g_main_context_push_thread_default(iothread->worker_context); + qemu_cond_signal(&iothread->init_done_cond); qemu_mutex_unlock(&iothread->init_done_lock); @@ -51,6 +78,7 @@ static void *iothread_run(void *opaque) aio_poll(iothread->ctx, true); } + g_main_context_pop_thread_default(iothread->worker_context); rcu_unregister_thread(); return NULL; } @@ -66,6 +94,8 @@ void iothread_join(IOThread *iothread) { aio_bh_schedule_oneshot(iothread->ctx, iothread_stop_bh, iothread); qemu_thread_join(&iothread->thread); + g_main_context_unref(iothread->worker_context); + g_main_loop_unref(iothread->main_loop); qemu_cond_destroy(&iothread->init_done_cond); qemu_mutex_destroy(&iothread->init_done_lock); aio_context_unref(iothread->ctx); diff --git a/tests/numa-test.c b/tests/numa-test.c index 8de8581231..17dd807d2a 100644 --- a/tests/numa-test.c +++ b/tests/numa-test.c @@ -327,6 +327,216 @@ static void pc_dynamic_cpu_cfg(const void *data) qtest_quit(qs); } +static void pc_hmat_build_cfg(const void *data) +{ + QTestState *qs = qtest_initf("%s -nodefaults --preconfig -machine hmat=on " + "-smp 2,sockets=2 " + "-m 128M,slots=2,maxmem=1G " + "-object memory-backend-ram,size=64M,id=m0 " + "-object memory-backend-ram,size=64M,id=m1 " + "-numa node,nodeid=0,memdev=m0 " + "-numa node,nodeid=1,memdev=m1,initiator=0 " + "-numa cpu,node-id=0,socket-id=0 " + "-numa cpu,node-id=0,socket-id=1", + data ? (char *)data : ""); + + /* Fail: Initiator should be less than the number of nodes */ + g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'hmat-lb', 'initiator': 2, 'target': 0," + " 'hierarchy': \"memory\", 'data-type': \"access-latency\" } }"))); + + /* Fail: Target should be less than the number of nodes */ + g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 2," + " 'hierarchy': \"memory\", 'data-type': \"access-latency\" } }"))); + + /* Fail: Initiator should contain cpu */ + g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'hmat-lb', 'initiator': 1, 'target': 0," + " 'hierarchy': \"memory\", 'data-type': \"access-latency\" } }"))); + + /* Fail: Data-type mismatch */ + g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0," + " 'hierarchy': \"memory\", 'data-type': \"write-latency\"," + " 'bandwidth': 524288000 } }"))); + g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0," + " 'hierarchy': \"memory\", 'data-type': \"read-bandwidth\"," + " 'latency': 5 } }"))); + + /* Fail: Bandwidth should be 1MB (1048576) aligned */ + g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0," + " 'hierarchy': \"memory\", 'data-type': \"access-bandwidth\"," + " 'bandwidth': 1048575 } }"))); + + /* Configuring HMAT bandwidth and latency details */ + g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0," + " 'hierarchy': \"memory\", 'data-type': \"access-latency\"," + " 'latency': 1 } }"))); /* 1 ns */ + g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0," + " 'hierarchy': \"memory\", 'data-type': \"access-latency\"," + " 'latency': 5 } }"))); /* Fail: Duplicate configuration */ + g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0," + " 'hierarchy': \"memory\", 'data-type': \"access-bandwidth\"," + " 'bandwidth': 68717379584 } }"))); /* 65534 MB/s */ + g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 1," + " 'hierarchy': \"memory\", 'data-type': \"access-latency\"," + " 'latency': 65534 } }"))); /* 65534 ns */ + g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 1," + " 'hierarchy': \"memory\", 'data-type': \"access-bandwidth\"," + " 'bandwidth': 34358689792 } }"))); /* 32767 MB/s */ + + /* Fail: node_id should be less than the number of nodes */ + g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'hmat-cache', 'node-id': 2, 'size': 10240," + " 'level': 1, 'associativity': \"direct\", 'policy': \"write-back\"," + " 'line': 8 } }"))); + + /* Fail: level should be less than HMAT_LB_LEVELS (4) */ + g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240," + " 'level': 4, 'associativity': \"direct\", 'policy': \"write-back\"," + " 'line': 8 } }"))); + + /* Fail: associativity option should be 'none', if level is 0 */ + g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240," + " 'level': 0, 'associativity': \"direct\", 'policy': \"none\"," + " 'line': 0 } }"))); + /* Fail: policy option should be 'none', if level is 0 */ + g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240," + " 'level': 0, 'associativity': \"none\", 'policy': \"write-back\"," + " 'line': 0 } }"))); + /* Fail: line option should be 0, if level is 0 */ + g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240," + " 'level': 0, 'associativity': \"none\", 'policy': \"none\"," + " 'line': 8 } }"))); + + /* Configuring HMAT memory side cache attributes */ + g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240," + " 'level': 1, 'associativity': \"direct\", 'policy': \"write-back\"," + " 'line': 8 } }"))); + g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240," + " 'level': 1, 'associativity': \"direct\", 'policy': \"write-back\"," + " 'line': 8 } }"))); /* Fail: Duplicate configuration */ + /* Fail: The size of level 2 size should be small than level 1 */ + g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240," + " 'level': 2, 'associativity': \"direct\", 'policy': \"write-back\"," + " 'line': 8 } }"))); + /* Fail: The size of level 0 size should be larger than level 1 */ + g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240," + " 'level': 0, 'associativity': \"direct\", 'policy': \"write-back\"," + " 'line': 8 } }"))); + g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'hmat-cache', 'node-id': 1, 'size': 10240," + " 'level': 1, 'associativity': \"direct\", 'policy': \"write-back\"," + " 'line': 8 } }"))); + + /* let machine initialization to complete and run */ + g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, + "{ 'execute': 'x-exit-preconfig' }"))); + qtest_qmp_eventwait(qs, "RESUME"); + + qtest_quit(qs); +} + +static void pc_hmat_off_cfg(const void *data) +{ + QTestState *qs = qtest_initf("%s -nodefaults --preconfig " + "-smp 2,sockets=2 " + "-m 128M,slots=2,maxmem=1G " + "-object memory-backend-ram,size=64M,id=m0 " + "-object memory-backend-ram,size=64M,id=m1 " + "-numa node,nodeid=0,memdev=m0", + data ? (char *)data : ""); + + /* + * Fail: Enable HMAT with -machine hmat=on + * before using any of hmat specific options + */ + g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'node', 'nodeid': 1, 'memdev': \"m1\"," + " 'initiator': 0 } }"))); + g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'node', 'nodeid': 1, 'memdev': \"m1\" } }"))); + g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0," + " 'hierarchy': \"memory\", 'data-type': \"access-latency\"," + " 'latency': 1 } }"))); + g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240," + " 'level': 1, 'associativity': \"direct\", 'policy': \"write-back\"," + " 'line': 8 } }"))); + + /* let machine initialization to complete and run */ + g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, + "{ 'execute': 'x-exit-preconfig' }"))); + qtest_qmp_eventwait(qs, "RESUME"); + + qtest_quit(qs); +} + +static void pc_hmat_erange_cfg(const void *data) +{ + QTestState *qs = qtest_initf("%s -nodefaults --preconfig -machine hmat=on " + "-smp 2,sockets=2 " + "-m 128M,slots=2,maxmem=1G " + "-object memory-backend-ram,size=64M,id=m0 " + "-object memory-backend-ram,size=64M,id=m1 " + "-numa node,nodeid=0,memdev=m0 " + "-numa node,nodeid=1,memdev=m1,initiator=0 " + "-numa cpu,node-id=0,socket-id=0 " + "-numa cpu,node-id=0,socket-id=1", + data ? (char *)data : ""); + + /* Can't store the compressed latency */ + g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0," + " 'hierarchy': \"memory\", 'data-type': \"access-latency\"," + " 'latency': 1 } }"))); /* 1 ns */ + g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 1," + " 'hierarchy': \"memory\", 'data-type': \"access-latency\"," + " 'latency': 65535 } }"))); /* 65535 ns */ + + /* Test the 0 input (bandwidth not provided) */ + g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0," + " 'hierarchy': \"memory\", 'data-type': \"access-bandwidth\"," + " 'bandwidth': 0 } }"))); /* 0 MB/s */ + /* Fail: bandwidth should be provided before memory side cache attributes */ + g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240," + " 'level': 1, 'associativity': \"direct\", 'policy': \"write-back\"," + " 'line': 8 } }"))); + + /* Can't store the compressed bandwidth */ + g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 1," + " 'hierarchy': \"memory\", 'data-type': \"access-bandwidth\"," + " 'bandwidth': 68718428160 } }"))); /* 65535 MB/s */ + + /* let machine initialization to complete and run */ + g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, + "{ 'execute': 'x-exit-preconfig' }"))); + qtest_qmp_eventwait(qs, "RESUME"); + + qtest_quit(qs); +} + int main(int argc, char **argv) { const char *args = NULL; @@ -346,6 +556,9 @@ int main(int argc, char **argv) if (!strcmp(arch, "i386") || !strcmp(arch, "x86_64")) { qtest_add_data_func("/numa/pc/cpu/explicit", args, pc_numa_cpu); qtest_add_data_func("/numa/pc/dynamic/cpu", args, pc_dynamic_cpu_cfg); + qtest_add_data_func("/numa/pc/hmat/build", args, pc_hmat_build_cfg); + qtest_add_data_func("/numa/pc/hmat/off", args, pc_hmat_off_cfg); + qtest_add_data_func("/numa/pc/hmat/erange", args, pc_hmat_erange_cfg); } if (!strcmp(arch, "ppc64")) { |