Skip to content

Commit 38b4950

Browse files
committed
test: run throughput perf tests with swiotlb enabled
On aarch64, additionally parametrize our throughput performance tests (network, block and vsock) by swiotlb size, to get a feeling for the performance impact bounce buffering will have. Try out different sizes of swiotlb region to see whether we can identify a cut off. Also add it to the boottime test, because swiotlb can impact the time taken to read the rootfs. Signed-off-by: Patrick Roy <roypat@amazon.co.uk>
1 parent 0363920 commit 38b4950

File tree

6 files changed

+69
-25
lines changed

6 files changed

+69
-25
lines changed

tests/conftest.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,19 @@ def io_engine(request):
376376
return request.param
377377

378378

379+
# 4MiB is the smallest swiotlb size that seems to generally work for all
380+
# perf tests. 2MiB makes the vsock throughput test consistently fail, and 1MiB makes
381+
# the network throughput test occasionally fail (both due to connection issues).
382+
# The block test passes even with the minimum of 1MiB. We pick 8 to have enough
383+
# buffer to the failing cases.
384+
@pytest.fixture(params=[None, 8] if platform.machine() == "aarch64" else [None])
385+
def memory_config(request):
386+
"""Differently configured swiotlb regions. Only supported on aarch64"""
387+
if request.param is None:
388+
return None
389+
return {"initial_swiotlb_size": request.param}
390+
391+
379392
@pytest.fixture
380393
def results_dir(request):
381394
"""

tests/framework/microvm.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ def __init__(
248248
self.disks_vhost_user = {}
249249
self.vcpus_count = None
250250
self.mem_size_bytes = None
251+
self.memory_config = None
251252
self.cpu_template_name = None
252253
# The given custom CPU template will be set in basic_config() but could
253254
# be overwritten via set_cpu_template().
@@ -462,6 +463,11 @@ def dimensions(self):
462463
"rootfs": self.rootfs_file.name,
463464
"vcpus": str(self.vcpus_count),
464465
"guest_memory": f"{self.mem_size_bytes / (1024 * 1024)}MB",
466+
**(
467+
{k: str(v) for k, v in self.memory_config.items()}
468+
if self.memory_config
469+
else {}
470+
),
465471
}
466472

467473
@property
@@ -729,6 +735,7 @@ def basic_config(
729735
rootfs_io_engine=None,
730736
cpu_template: Optional[str] = None,
731737
enable_entropy_device=False,
738+
memory_config=None,
732739
):
733740
"""Shortcut for quickly configuring a microVM.
734741
@@ -747,15 +754,23 @@ def basic_config(
747754
748755
Reference: file:../../src/vmm/src/vmm_config/boot_source.rs::DEFAULT_KERNEL_CMDLINE
749756
"""
757+
# Have to do it this way as otherwise A/B-tests fail if the 'A' revision
758+
# of Firecracker doesn't know about the mem_config parameter.
759+
kwargs = {}
760+
if memory_config is not None:
761+
kwargs["mem_config"] = memory_config
762+
750763
self.api.machine_config.put(
751764
vcpu_count=vcpu_count,
752765
smt=smt,
753766
mem_size_mib=mem_size_mib,
754767
track_dirty_pages=track_dirty_pages,
755768
huge_pages=huge_pages,
769+
**kwargs,
756770
)
757771
self.vcpus_count = vcpu_count
758772
self.mem_size_bytes = mem_size_mib * 2**20
773+
self.memory_config = memory_config
759774

760775
if self.custom_cpu_template is not None:
761776
self.set_cpu_template(self.custom_cpu_template)

tests/integration_tests/performance/test_block_ab.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,14 +148,20 @@ def test_block_performance(
148148
fio_mode,
149149
fio_block_size,
150150
io_engine,
151+
memory_config,
151152
metrics,
152153
):
153154
"""
154155
Execute block device emulation benchmarking scenarios.
155156
"""
157+
if memory_config is not None and "6.1" not in guest_kernel_acpi.name:
158+
pytest.skip("swiotlb only supported on aarch64/6.1")
159+
156160
vm = microvm_factory.build(guest_kernel_acpi, rootfs, monitor_memory=False)
157161
vm.spawn(log_level="Info", emit_metrics=True)
158-
vm.basic_config(vcpu_count=vcpus, mem_size_mib=GUEST_MEM_MIB)
162+
vm.basic_config(
163+
vcpu_count=vcpus, mem_size_mib=GUEST_MEM_MIB, memory_config=memory_config
164+
)
159165
vm.add_net_iface()
160166
# Add a secondary block device for benchmark tests.
161167
fs = drive_tools.FilesystemFile(

tests/integration_tests/performance/test_boottime.py

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88

99
import pytest
1010

11-
from framework.properties import global_props
12-
1311
# Regex for obtaining boot time from some string.
1412
TIMESTAMP_LOG_REGEX = r"Guest-boot-time\s+\=\s+(\d+)\s+us"
1513

@@ -19,14 +17,6 @@
1917
)
2018

2119

22-
DIMENSIONS = {
23-
"instance": global_props.instance,
24-
"cpu_model": global_props.cpu_model,
25-
"host_os": global_props.host_os,
26-
"host_kernel": "linux-" + global_props.host_linux_version_metrics,
27-
}
28-
29-
3020
def _get_microvm_boottime(vm):
3121
"""Auxiliary function for asserting the expected boot time."""
3222
boot_time_us = None
@@ -75,19 +65,18 @@ def find_events(log_data):
7565
)
7666
@pytest.mark.nonci
7767
def test_boottime(
78-
microvm_factory, guest_kernel_acpi, rootfs_rw, vcpu_count, mem_size_mib, metrics
68+
microvm_factory,
69+
guest_kernel_acpi,
70+
rootfs_rw,
71+
vcpu_count,
72+
mem_size_mib,
73+
memory_config,
74+
metrics,
7975
):
8076
"""Test boot time with different guest configurations"""
8177

82-
metrics.set_dimensions(
83-
{
84-
**DIMENSIONS,
85-
"performance_test": "test_boottime",
86-
"guest_kernel": guest_kernel_acpi.name,
87-
"vcpus": str(vcpu_count),
88-
"mem_size_mib": str(mem_size_mib),
89-
}
90-
)
78+
if memory_config is not None and "6.1" not in guest_kernel_acpi.name:
79+
pytest.skip("swiotlb only supported on aarch64/6.1")
9180

9281
for _ in range(10):
9382
vm = microvm_factory.build(guest_kernel_acpi, rootfs_rw)
@@ -98,10 +87,14 @@ def test_boottime(
9887
mem_size_mib=mem_size_mib,
9988
boot_args=DEFAULT_BOOT_ARGS + " init=/usr/local/bin/init",
10089
enable_entropy_device=True,
90+
memory_config=memory_config,
10191
)
10292
vm.add_net_iface()
10393
vm.start()
10494
vm.pin_threads(0)
95+
96+
metrics.set_dimensions({"performance_test": "test_boottime", **vm.dimensions})
97+
10598
boottime_us = _get_microvm_boottime(vm)
10699
metrics.put_metric("boot_time", boottime_us, unit="Microseconds")
107100
timestamps = find_events(vm.log_data)

tests/integration_tests/performance/test_network_ab.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,21 @@ def consume_ping_output(ping_putput, request_per_round):
3636

3737

3838
@pytest.fixture
39-
def network_microvm(request, microvm_factory, guest_kernel_acpi, rootfs):
39+
def network_microvm(request, microvm_factory, guest_kernel_acpi, rootfs, memory_config):
4040
"""Creates a microvm with the networking setup used by the performance tests in this file.
4141
This fixture receives its vcpu count via indirect parameterization"""
4242

43+
if memory_config is not None and "6.1" not in guest_kernel_acpi.name:
44+
pytest.skip("swiotlb only supported on aarch64/6.1")
45+
4346
guest_mem_mib = 1024
4447
guest_vcpus = request.param
4548

4649
vm = microvm_factory.build(guest_kernel_acpi, rootfs, monitor_memory=False)
4750
vm.spawn(log_level="Info", emit_metrics=True)
48-
vm.basic_config(vcpu_count=guest_vcpus, mem_size_mib=guest_mem_mib)
51+
vm.basic_config(
52+
vcpu_count=guest_vcpus, mem_size_mib=guest_mem_mib, memory_config=memory_config
53+
)
4954
vm.add_net_iface()
5055
vm.start()
5156
vm.pin_threads(0)

tests/integration_tests/performance/test_vsock_ab.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,14 @@ def guest_command(self, port_offset):
7373
@pytest.mark.parametrize("payload_length", ["64K", "1024K"], ids=["p64K", "p1024K"])
7474
@pytest.mark.parametrize("mode", ["g2h", "h2g", "bd"])
7575
def test_vsock_throughput(
76-
microvm_factory, guest_kernel_acpi, rootfs, vcpus, payload_length, mode, metrics
76+
microvm_factory,
77+
guest_kernel_acpi,
78+
rootfs,
79+
vcpus,
80+
payload_length,
81+
mode,
82+
metrics,
83+
memory_config,
7784
):
7885
"""
7986
Test vsock throughput for multiple vm configurations.
@@ -84,10 +91,15 @@ def test_vsock_throughput(
8491
if mode == "bd" and vcpus < 2:
8592
pytest.skip("bidrectional test only done with at least 2 vcpus")
8693

94+
if memory_config is not None and "6.1" not in guest_kernel_acpi.name:
95+
pytest.skip("swiotlb only supported on aarch64/6.1")
96+
8797
mem_size_mib = 1024
8898
vm = microvm_factory.build(guest_kernel_acpi, rootfs, monitor_memory=False)
8999
vm.spawn(log_level="Info", emit_metrics=True)
90-
vm.basic_config(vcpu_count=vcpus, mem_size_mib=mem_size_mib)
100+
vm.basic_config(
101+
vcpu_count=vcpus, mem_size_mib=mem_size_mib, memory_config=memory_config
102+
)
91103
vm.add_net_iface()
92104
# Create a vsock device
93105
vm.api.vsock.put(vsock_id="vsock0", guest_cid=3, uds_path="/" + VSOCK_UDS_PATH)

0 commit comments

Comments
 (0)