From 22cf10b6ab6ad6f8d447a835e6f0dfd5ccca6b09 Mon Sep 17 00:00:00 2001 From: Sebastian Eydam Date: Thu, 26 Feb 2026 16:52:42 +0100 Subject: [PATCH] vmm: return error if prefaulting fails Prefaulting pages was done on a best-effort basis before, meaning that errors were ignored. This could lead to errors during runtime, especially when used with hugepages, because there was no guarantee that enough pages are available. With this change errors during prefaulting will be reported. Co-authored-by: Philipp Schuster On-behalf-of: SAP philipp.schuster@sap.com Signed-off-by: Philipp Schuster On-behalf-of: SAP sebastian.eydam@sap.com Signed-off-by: Sebastian Eydam --- vmm/src/memory_manager.rs | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/vmm/src/memory_manager.rs b/vmm/src/memory_manager.rs index 44b0ccda3..1ab51dc19 100644 --- a/vmm/src/memory_manager.rs +++ b/vmm/src/memory_manager.rs @@ -415,6 +415,10 @@ pub enum Error { /// Memory size is misaligned with default page size or its hugepage size #[error("Memory size is misaligned with default page size or its hugepage size")] MisalignedMemorySize, + + /// Failed to prefault memory + #[error("Failed to prefault memory")] + PrefaultMemory(#[source] io::Error), } impl From for Error { @@ -2083,11 +2087,12 @@ impl MemoryManager { let remainder = num_pages % num_threads; let barrier = Arc::new(Barrier::new(num_threads)); - thread::scope(|s| { + thread::scope(|s| -> Result<(), Error> { let r = ®ion; + let mut handles = Vec::new(); for i in 0..num_threads { let barrier = Arc::clone(&barrier); - s.spawn(move || { + let handle = s.spawn(move || { // Wait until all threads have been spawned to avoid contention // over mmap_sem between thread stack allocation and page faulting. barrier.wait(); @@ -2100,11 +2105,26 @@ impl MemoryManager { }; if ret != 0 { let e = io::Error::last_os_error(); - warn!("Failed to prefault pages: {e}"); + return Err(e); } + Ok(()) }); + handles.push(handle); } - }); + + for handle in handles { + handle + .join() + .map_err(|e| { + Error::PrefaultMemory(io::Error::other(format!( + "Prefault thread panicked: {e:?}" + ))) + })? + .map_err(Error::PrefaultMemory)?; + } + + Ok(()) + })?; } info!(