The raw sync, io_uring and AIO workers now own an AlignedFile and use
it for the O_DIRECT alignment value and for the unaligned fallback.
Aligned operations keep the fast preadv and pwritev iovec path straight
to the kernel. When the offset or an iovec base or length is not a
multiple of the probed alignment, the worker gathers the iovecs into
one contiguous host buffer and runs a synchronous RMW through
AlignedFile, then scatters the result back into guest memory.
RawDisk constructs the AlignedFile from the disk file and the direct
flag and passes it into each worker, so alignment is probed once at
open time. The fixed VHD workers are threaded through the same
AlignedFile based constructors using a non-direct AlignedFile to
preserve current behavior.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
The boot time tests inferred guest readiness from the two debug I/O
port markers on stderr. Heavier boots could miss the fixed sleep
window, capture a single marker, and panic.
Wait on the cloud-init injected notify-booted callback through
guest.wait_vm_boot() instead. Once the callback fires, both markers
are guaranteed present, so they are parsed only for the metric. The
host side keeps an overall timeout, so a guest that never boots is
still reaped.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Import the std modules used in the crate instead of spelling the full
paths at every use site, and drop the now-unnecessary crate-level
#![expect(clippy::absolute_paths)].
Signed-off-by: Henry Hrvoje Tonkovac <htonkovac@gmail.com>
Assisted-by: Claude:Opus-4.8
Convert the still-needed #[allow] to #[expect] so it warns if the
lint stops firing.
Part of #8326.
Signed-off-by: Tushar Khatri <hello@tusharkhatri.in>
Removal of absolute paths is currently in progress. To avoid regressing
those changes add a clippy deny at the workspace level and at the crate
level override with #[expect(clippy::absolute_paths)]
See: #7670
Signed-off-by: Rob Bradford <rbradford@meta.com>
Switch from QcowFile to QcowDisk taking advantage of QcowTempDisk where
appropriate.
Assisted-by: Claude:claude-opus-4-7
Signed-off-by: Rob Bradford <rbradford@meta.com>
Update external consumers to use formats::qcow::internal instead
of the top level qcow alias. Keep a crate private use for the
QcowError variant in lib.rs.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Update external consumers and internal test modules to use
formats::raw instead of the raw_disk alias, then remove the
re-export from lib.rs.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Move QCOW2 format implementation into a structured directory layout:
qcow/ -> formats/qcow/internal/ (filenames unchanged)
qcow_disk.rs -> formats/qcow/mod.rs (QcowDisk)
qcow_sync.rs -> formats/qcow/worker/sync.rs (QcowSync)
qcow_async.rs -> formats/qcow/worker/async_uring.rs (QcowAsync)
qcow_common.rs -> formats/qcow/common.rs
All internal cross references continue to resolve through
re-exports in lib.rs: formats::qcow::internal as qcow,
formats::qcow as qcow_disk, and
formats::qcow::common as qcow_common.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Drop the borrowed iovec AsyncIo entry points now that all callers use
owned operations. Rename the transitional owned batch and completion
methods to the final trait names and remove the borrowed submission
helpers from the queue wrappers.
This removes a bunch of known safety foot-guns so future-us don't
accidentally use them.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Dylan Reid <dgreid@fb.com>
Switch the in-process block microbenchmarks to allocate prefaulted
GuestMemory regions and submit through the memory-target AsyncIo API.
This adds a few setup steps as the existing benchmarks relied on the
unsound iovec API. The new behavior is intended to be as close as
possible to the existing tests and the common path for running
cloud-hypervisor.
Assisted-by: Codex:GPT-5.5
Assisted-by: Claude:Opus-4.7
Signed-off-by: Dylan Reid <dgreid@fb.com>
Focal has served us well for many years but is now beyond EOL. Remove
all remaining use of focal images from the CI.
Signed-off-by: Rob Bradford <rbradford@meta.com>
Replace explicit --cpus boot=N arguments with .default_cpus()
in all performance test functions. For confidential guests,
nested=on is not supported, so using default_cpus() ensures
nested=off is correctly set for confidential VMs.
The net throughput, net latency, and block I/O tests now set
guest.num_cpu to the number of queues before calling
default_cpus(), ensuring the correct vCPU count is used.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Refactor performance_test_new_guest to accept the full
PerformanceTestControl reference instead of just GuestVmType.
This allows the function to also set guest.num_cpu from
control.num_boot_vcpus, ensuring the guest is configured
with the correct number of vCPUs for the test.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Use into_iter() for test_list when building tests_to_run.
This keeps the collected type as Vec<&PerformanceTest>.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Replace explicit --kernel and --cmdline arguments with the
default_kernel_cmdline() helper in performance_net_throughput,
performance_net_latency, and performance_block_io. This
simplifies the code and ensures consistency with how the
kernel command line is configured across tests.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Confidential VMs (CVM) are not currently supported on the
AArch64 architecture. Add an early check in the performance
metrics binary to exit with a clear error message when CVM
mode is selected on AArch64.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Add a --vm-type command-line argument to allow users to select
between 'regular' (default) and 'confidential' (CVM) VM types
when running performance tests.
Example: --vm-type confidential
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Apply the vm_type override from PerformanceTestOverrides to the
effective_control used during test execution, alongside the
existing test_timeout override.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Add an optional vm_type field to PerformanceTestOverrides to
allow overriding the VM type at runtime. Include vm_type in
the Display output for override logging.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Replace hardcoded GuestVmType::Regular with control.vm_type
in all performance test functions to support CVM benchmarking:
net_throughput, net_latency, boot_time, boot_time_pmem,
block_io, and restore_latency.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Update performance_test_new_guest() to accept a GuestVmType
parameter. When set to Confidential, configure the guest with
CVM-specific settings: vm_type, boot_timeout, and nested
virtualization disabled.
All callers pass GuestVmType::Regular to preserve existing
behavior.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Add a vm_type field of type GuestVmType to PerformanceTestControl,
defaulting to GuestVmType::Regular. Include vm_type in the Display
output for test control logging.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Consolidate override application into a single effective_control
variable built once before the test loop. This removes duplicated
timeout override logic from both warmup and measurement iterations.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Replace QcowDiskSync and QcowDiskAsync with QcowDisk in all QCOW2
benchmark helpers. The sync helpers pass use_io_uring=false, the
async helpers pass use_io_uring=true.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Replace direct RawFileAsyncAio construction with RawDisk
and create_async_io, consistent with the unified API.
Assisted-by: Claude:Opus-4.6
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
The new_ prefix in Rust conventionally denotes constructors that return
Self (e.g. Vec::new(), File::new()). AsyncDiskFile::new_async_io does
not return Self. It is a factory method that constructs and returns a
Box<dyn AsyncIo> worker bound to the disk file descriptor and
metadata. The create_ prefix communicates this: the caller receives
a freshly constructed object of a different type.
This rename touches every format backend in block plus two external
callers in virtio-devices and performance-metrics. Every change is a
mechanical s/new_async_io/create_async_io/ substitution. No functional
change.
Ref: #7877 (task 3.2.8)
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Use thread::Builder to give the test thread a name matching the
test so Guest picks it up automatically. After every test, call
ProcessRegistry::cleanup() to kill the process group instead of
the old pkill based cleanup_stale_processes().
Remove cleanup_stale_processes() and its call sites.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add micro_bench_qcow_batch_write which builds a batch of num_ops
write requests and submits them all at once through
submit_batch_requests. Writes in QcowAsync are synchronous (COW
path), so this measures whether batching reduces per-request
overhead compared to individual write_vectored calls.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add micro_bench_qcow_async_l2_cache_miss which reads one cluster
from each of num_ops distinct L2 tables through the QcowAsync
io_uring path, forcing L2 cache eviction on nearly every read.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add sparse_qcow_async_tempfile which creates a sparse QCOW2 image
with one cluster per L2 table and opens it via QcowDiskAsync.
Mirrors the existing sparse_qcow_tempfile for io_uring benchmarks.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add micro_bench_qcow_async_write which writes clusters into an
empty QCOW2 image through the QcowAsync io_uring path. Writes
in QcowAsync are synchronous due to COW metadata allocation, so
this measures the write path overhead through the async code path.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add empty_qcow_async_tempfile which creates an empty QCOW2 image
and opens it via QcowDiskAsync. Mirrors the existing
empty_qcow_tempfile for io_uring write benchmarks.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add micro_bench_qcow_async_compressed_read which reads from a
zlib compressed QCOW2 image through the QcowAsync io_uring path.
Compressed clusters take the sync fallback since they require
decompression.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add compressed_qcow_async_tempfile which creates a zlib compressed
QCOW2 image via qemu-img and opens it via QcowDiskAsync. Mirrors
the existing compressed_qcow_tempfile for io_uring benchmarks.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add micro_bench_qcow_async_backing_read which reads clusters from
a QCOW2 overlay through the QcowAsync io_uring path. All reads
fall through to the backing file, exercising the sync fallback
path in QcowAsync.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add qcow_async_overlay_tempfile which creates a QCOW2 overlay
backed by a RAW file and opens it via QcowDiskAsync. Mirrors
the existing qcow_overlay_tempfile for io_uring benchmarks.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add micro_bench_qcow_async_multi_cluster_read which reads 8
contiguous clusters (512 KiB) per request through the QcowAsync
io_uring path. With coalesced mappings this can hit the io_uring
fast path for a single Readv SQE.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add micro_bench_qcow_async_random_read which reads clusters in
random order through the QcowAsync io_uring path. This mirrors
the existing sync random read benchmark and measures io_uring
completion handling under random access patterns.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add micro_bench_qcow_batch_read which builds a batch of num_ops
read requests and submits them all at once through
submit_batch_requests. This exercises the io_uring batch
submission path added in qcow_async, where multiple SQEs are
packed into a single io_uring_enter call.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add micro_bench_qcow_async_read which reads clusters through the
QcowDiskAsync io_uring backend. Single allocated cluster reads go
through io_uring for true asynchronous completion, unlike the sync
benchmarks which use QcowDiskSync with blocking I/O.
Workloads: 128 and 256 clusters.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add micro_bench_qcow_l2_cache_miss which reads one cluster from each
of num_ops distinct L2 tables in a sparsely allocated image. Clusters
are spaced L2_ENTRIES_PER_TABLE apart so every read touches a different
L2 table, forcing eviction when num_ops exceeds the cache capacity.
Workloads: 128 and 256 L2 tables.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add sparse_qcow_tempfile() which creates a QCOW2 image with one
allocated cluster per L2 table, spread across num_l2_tables distinct
L2 tables. Reading these clusters in sequence forces L2 cache misses
when the count exceeds the cache capacity.
Also add the L2_ENTRIES_PER_TABLE constant, 8192 for 64 KiB clusters.
To be used by the L2 cache cold miss benchmark.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add micro_bench_qcow_multi_cluster_read which issues large reads
spanning 8 contiguous clusters (512 KiB) per read_vectored call.
This exercises the mapping coalesce path where multiple L2 entries
are merged into fewer host I/O operations.
Workloads: 128 and 256 total clusters (16 and 32 reads).
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add micro_bench_qcow_compressed_read which reads clusters from a
zlib compressed QCOW2 image. Every cluster triggers decompression,
isolating the decompression overhead from the normal allocated cluster
read path.
Workloads: 128 and 256 clusters.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add compressed_qcow_tempfile() which creates a zlib compressed QCOW2
image by populating a RAW tempfile with data and converting it via
qemu-img convert -c. Every cluster in the resulting image is stored
compressed so reads exercise the decompression path.
To be used by the compressed read benchmark.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>