Skip to content

Commit 810535f

Browse files
amphiphip1611
authored andcommitted
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 <philipp.schuster@cyberus-technology.de> On-behalf-of: SAP philipp.schuster@sap.com Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de> On-behalf-of: SAP sebastian.eydam@sap.com Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de> (cherry picked from commit 22cf10b)
1 parent 2d60f71 commit 810535f

1 file changed

Lines changed: 24 additions & 4 deletions

File tree

‎vmm/src/memory_manager.rs‎

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,10 @@ pub enum Error {
439439
/// Memory size is misaligned with default page size or its hugepage size
440440
#[error("Memory size is misaligned with default page size or its hugepage size")]
441441
MisalignedMemorySize,
442+
443+
/// Failed to prefault memory
444+
#[error("Failed to prefault memory")]
445+
PrefaultMemory(#[source] io::Error),
442446
}
443447

444448
impl From<UffdError> for Error {
@@ -1991,11 +1995,12 @@ impl MemoryManager {
19911995
let remainder = num_pages % num_threads;
19921996

19931997
let barrier = Arc::new(Barrier::new(num_threads));
1994-
thread::scope(|s| {
1998+
thread::scope(|s| -> Result<(), Error> {
19951999
let r = &region;
2000+
let mut handles = Vec::new();
19962001
for i in 0..num_threads {
19972002
let barrier = Arc::clone(&barrier);
1998-
s.spawn(move || {
2003+
let handle = s.spawn(move || {
19992004
// Wait until all threads have been spawned to avoid contention
20002005
// over mmap_sem between thread stack allocation and page faulting.
20012006
barrier.wait();
@@ -2009,11 +2014,26 @@ impl MemoryManager {
20092014
};
20102015
if ret != 0 {
20112016
let e = io::Error::last_os_error();
2012-
warn!("Failed to prefault pages: {e}");
2017+
return Err(e);
20132018
}
2019+
Ok(())
20142020
});
2021+
handles.push(handle);
20152022
}
2016-
});
2023+
2024+
for handle in handles {
2025+
handle
2026+
.join()
2027+
.map_err(|e| {
2028+
Error::PrefaultMemory(io::Error::other(format!(
2029+
"Prefault thread panicked: {e:?}"
2030+
)))
2031+
})?
2032+
.map_err(Error::PrefaultMemory)?;
2033+
}
2034+
2035+
Ok(())
2036+
})?;
20172037
}
20182038

20192039
info!(

0 commit comments

Comments
 (0)