mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
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>
This commit is contained in:
@@ -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<UffdError> 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!(
|
||||
|
||||
Reference in New Issue
Block a user