-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Test latency of hotplugging via udev and manual agent Signed-off-by: James Curtis <[email protected]>
- Loading branch information
1 parent
e6c2c93
commit 0e3be4b
Showing
10 changed files
with
236 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
SUBSYSTEM=="cpu", ACTION=="add", ATTR{online}!="1", ATTR{online}="1" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#!/bin/bash | ||
# Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
while :; do | ||
[[ -d /sys/devices/system/cpu/cpu$1 ]] && break | ||
done | ||
|
||
echo 1 | tee /sys/devices/system/cpu/cpu*/online | ||
|
||
/home/hotplug_time.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
// Init wrapper for boot timing. It points at /sbin/init. | ||
|
||
#include <fcntl.h> | ||
#include <sys/mman.h> | ||
#include <sys/types.h> | ||
#include <unistd.h> | ||
|
||
// Base address values are defined in arch/src/lib.rs as arch::MMIO_MEM_START. | ||
// Values are computed in arch/src/<arch>/mod.rs from the architecture layouts. | ||
// Position on the bus is defined by MMIO_LEN increments, where MMIO_LEN is | ||
// defined as 0x1000 in vmm/src/device_manager/mmio.rs. | ||
#ifdef __x86_64__ | ||
#define MAGIC_MMIO_SIGNAL_GUEST_BOOT_COMPLETE 0xd0000000 | ||
#endif | ||
#ifdef __aarch64__ | ||
#define MAGIC_MMIO_SIGNAL_GUEST_BOOT_COMPLETE 0x40000000 | ||
#endif | ||
|
||
#define MAGIC_VALUE_SIGNAL_GUEST_BOOT_COMPLETE 123 | ||
|
||
int main() { | ||
int fd = open("/dev/mem", (O_RDWR | O_SYNC | O_CLOEXEC)); | ||
int mapped_size = getpagesize(); | ||
|
||
char *map_base = mmap(NULL, mapped_size, PROT_WRITE, MAP_SHARED, fd, | ||
MAGIC_MMIO_SIGNAL_GUEST_BOOT_COMPLETE); | ||
|
||
*map_base = MAGIC_VALUE_SIGNAL_GUEST_BOOT_COMPLETE; | ||
msync(map_base, mapped_size, MS_ASYNC); | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#!/bin/bash | ||
# Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
while :; do | ||
[[ $(nproc) == $1 ]] && break | ||
done | ||
|
||
/home/hotplug_time.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
152 changes: 152 additions & 0 deletions
152
tests/integration_tests/performance/test_vcpu_hotplug.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
# Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
"""Testing hotplug performance""" | ||
|
||
import platform | ||
import re | ||
import time | ||
from pathlib import Path | ||
|
||
import pandas | ||
import pytest | ||
|
||
from framework.utils_iperf import IPerf3Test, emit_iperf3_metrics | ||
from host_tools.cargo_build import gcc_compile | ||
from host_tools.fcmetrics import FCMetricsMonitor | ||
|
||
|
||
@pytest.mark.skipif( | ||
platform.machine() != "x86_64", reason="Hotplug only enabled on x86_64." | ||
) | ||
@pytest.mark.parametrize( | ||
"vcpu_count", [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30] | ||
) | ||
def test_custom_udev_rule_latency( | ||
microvm_factory, guest_kernel_linux_acpi_only, rootfs_rw, vcpu_count, results_dir | ||
): | ||
"""Test the latency for hotplugging and booting CPUs in the guest""" | ||
gcc_compile(Path("./host_tools/hotplug_time.c"), Path("host_tools/hotplug_time.o")) | ||
data = [] | ||
for i in range(50): | ||
uvm_hotplug = microvm_factory.build(guest_kernel_linux_acpi_only, rootfs_rw) | ||
uvm_hotplug.jailer.extra_args.update({"boot-timer": None, "no-seccomp": None}) | ||
uvm_hotplug.help.enable_console() | ||
uvm_hotplug.spawn() | ||
uvm_hotplug.basic_config(vcpu_count=1, mem_size_mib=128) | ||
uvm_hotplug.add_net_iface() | ||
uvm_hotplug.start() | ||
uvm_hotplug.ssh.scp_put( | ||
Path("./host_tools/hotplug_udev.sh"), Path("/home/hotplug_udev.sh") | ||
) | ||
uvm_hotplug.ssh.scp_put( | ||
Path("./host_tools/hotplug_time.o"), Path("/home/hotplug_time.o") | ||
) | ||
uvm_hotplug.ssh.scp_put( | ||
Path("./host_tools/1-cpu-hotplug.rules"), | ||
Path("/usr/lib/udev/rules.d/1-cpu-hotplug.rules"), | ||
) | ||
uvm_hotplug.ssh.run( | ||
f"udevadm control --reload-rules && tmux new-session -d /bin/bash /home/hotplug_udev.sh {vcpu_count}" | ||
) | ||
|
||
uvm_hotplug.api.hotplug.put(Vcpu={"add": vcpu_count}) | ||
time.sleep(2) | ||
|
||
# Extract API call duration | ||
api_duration = ( | ||
float( | ||
re.findall( | ||
r"Total previous API call duration: (\d+) us\.", | ||
uvm_hotplug.log_data, | ||
)[-1] | ||
) | ||
/ 1000 | ||
) | ||
try: | ||
timestamp = ( | ||
float( | ||
re.findall( | ||
r"Guest-boot-time\s+\=\s+(\d+)\s+us", uvm_hotplug.log_data | ||
)[0] | ||
) | ||
/ 1000 | ||
) | ||
except IndexError: | ||
timestamp = None | ||
|
||
data.append({"vcpus": vcpu_count, "api": api_duration, "onlining": timestamp}) | ||
|
||
output_file = results_dir / f"hotplug-{vcpu_count}.csv" | ||
|
||
csv_data = pandas.DataFrame.from_dict(data).to_csv( | ||
index=False, | ||
float_format="%.3f", | ||
) | ||
|
||
output_file.write_text(csv_data) | ||
|
||
|
||
@pytest.mark.skipif( | ||
platform.machine() != "x86_64", reason="Hotplug only enabled on x86_64." | ||
) | ||
@pytest.mark.parametrize( | ||
"vcpu_count", [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30] | ||
) | ||
def test_manual_latency( | ||
microvm_factory, guest_kernel_linux_acpi_only, rootfs_rw, vcpu_count | ||
): | ||
"""Test the latency for hotplugging and booting CPUs in the guest""" | ||
gcc_compile(Path("./host_tools/hotplug_time.c"), Path("host_tools/hotplug_time.o")) | ||
data = [] | ||
for _ in range(50): | ||
uvm_hotplug = microvm_factory.build(guest_kernel_linux_acpi_only, rootfs_rw) | ||
uvm_hotplug.jailer.extra_args.update({"boot-timer": None, "no-seccomp": None}) | ||
uvm_hotplug.help.enable_console() | ||
uvm_hotplug.spawn() | ||
uvm_hotplug.basic_config(vcpu_count=1, mem_size_mib=128) | ||
uvm_hotplug.add_net_iface() | ||
uvm_hotplug.start() | ||
uvm_hotplug.ssh.scp_put( | ||
Path("./host_tools/hotplug.sh"), Path("/home/hotplug.sh") | ||
) | ||
uvm_hotplug.ssh.scp_put( | ||
Path("./host_tools/hotplug_time.o"), Path("/home/hotplug_time.o") | ||
) | ||
uvm_hotplug.ssh.run("tmux new-session -d /bin/bash /home/hotplug.sh") | ||
|
||
uvm_hotplug.api.hotplug.put(Vcpu={"add": vcpu_count}) | ||
|
||
time.sleep(1.5) | ||
# Extract API call duration | ||
api_duration = ( | ||
float( | ||
re.findall( | ||
r"Total previous API call duration: (\d+) us\.", | ||
uvm_hotplug.log_data, | ||
)[-1] | ||
) | ||
/ 1000 | ||
) | ||
try: | ||
timestamp = ( | ||
float( | ||
re.findall( | ||
r"Guest-boot-time\s+\=\s+(\d+)\s+us", uvm_hotplug.log_data | ||
)[0] | ||
) | ||
/ 1000 | ||
) | ||
except IndexError: | ||
data.append({"vcpus": vcpu_count, "api": api_duration, "onlining": None}) | ||
continue | ||
|
||
data.append({"vcpus": vcpu_count, "api": api_duration, "onlining": timestamp}) | ||
|
||
df = pandas.DataFrame.from_dict(data).to_csv( | ||
f"../test_results/manual-hotplug_{vcpu_count}.csv", | ||
index=False, | ||
float_format="%.3f", | ||
) | ||
|
||
output_file.write_text(csv_data) |