mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2024-11-24 20:48:55 +00:00
swap: vmm-swap in concurrently
A page fault handling may be executed concurrently during swapping in. This is the first step of vmm-swap in optimization. At the last step (https://crrev.com/c/4317028), the background thread executes swapping in. BUG=b:265606668 TEST=cargo test -p swap Change-Id: I42ec6b75485c31c9db26c22aa115b50288951b06 Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/4314185 Reviewed-by: Daniel Verkamp <dverkamp@chromium.org> Reviewed-by: David Stevens <stevensd@chromium.org> Commit-Queue: Shin Kawamura <kawasin@google.com>
This commit is contained in:
parent
c30a6ac4ea
commit
06371af4fa
1 changed files with 40 additions and 36 deletions
|
@ -104,6 +104,10 @@ impl From<&SwapState> for State {
|
|||
direction: SwapDirection::Out,
|
||||
..
|
||||
} => State::SwapOutInProgress,
|
||||
SwapState::InProgress {
|
||||
direction: SwapDirection::In,
|
||||
..
|
||||
} => State::SwapInInProgress,
|
||||
SwapState::SwapOutCompleted => State::Active,
|
||||
SwapState::Failed => State::Failed,
|
||||
}
|
||||
|
@ -547,29 +551,9 @@ fn start_monitoring<'a>(
|
|||
Ok(page_hander)
|
||||
}
|
||||
|
||||
fn disable_monitoring(
|
||||
mut page_handler: PageHandler,
|
||||
uffd_list: &UffdList,
|
||||
guest_memory: &GuestMemory,
|
||||
) -> anyhow::Result<usize> {
|
||||
let mut num_pages = 0;
|
||||
loop {
|
||||
let pages = page_handler
|
||||
.swap_in(uffd_list.main_uffd(), MAX_SWAP_CHUNK_SIZE)
|
||||
.context("unregister all regions")?;
|
||||
if pages == 0 {
|
||||
break;
|
||||
}
|
||||
num_pages += pages;
|
||||
}
|
||||
let regions = regions_from_guest_memory(guest_memory);
|
||||
unregister_regions(®ions, uffd_list.get_list()).context("unregister regions")?;
|
||||
Ok(num_pages)
|
||||
}
|
||||
|
||||
enum SwapDirection {
|
||||
Out,
|
||||
// TODO(b/265606668): Add `In` to swap-in concurrently.
|
||||
In,
|
||||
}
|
||||
|
||||
enum SwapState {
|
||||
|
@ -642,6 +626,28 @@ fn monitor_process(
|
|||
state = SwapState::SwapOutCompleted;
|
||||
}
|
||||
}
|
||||
// TODO(b/265606668): execute swap-in on a background thread.
|
||||
SwapDirection::In => {
|
||||
let num_pages = page_handler
|
||||
.swap_in(uffd_list.main_uffd(), MAX_SWAP_CHUNK_SIZE)
|
||||
.context("swap in")?;
|
||||
state_transition.pages += num_pages;
|
||||
state_transition.time_ms = started_time.elapsed().as_millis();
|
||||
if num_pages == 0 {
|
||||
info!(
|
||||
"swap in all {} pages in {} ms.",
|
||||
state_transition.pages, state_transition.time_ms
|
||||
);
|
||||
page_handler_opt = None;
|
||||
let regions = regions_from_guest_memory(&guest_memory);
|
||||
unregister_regions(®ions, uffd_list.get_list())
|
||||
.context("unregister regions")?;
|
||||
// Truncate the swap file to hold minimum resources while disabled.
|
||||
swap_file.set_len(0).context("clear swap file")?;
|
||||
info!("vmm-swap is disabled.");
|
||||
state = SwapState::Disabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -811,23 +817,21 @@ fn monitor_process(
|
|||
} => {
|
||||
info!("swap out is aborted.");
|
||||
}
|
||||
SwapState::InProgress {
|
||||
direction: SwapDirection::In,
|
||||
..
|
||||
} => {
|
||||
info!("swap in is in progress.");
|
||||
continue;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
if let Some(page_handler) = page_handler_opt.take() {
|
||||
let t0 = std::time::Instant::now();
|
||||
state_transition.pages =
|
||||
disable_monitoring(page_handler, &uffd_list, &guest_memory)?;
|
||||
state_transition.time_ms = t0.elapsed().as_millis();
|
||||
info!(
|
||||
"swap in all {} pages in {} ms. swap disabled.",
|
||||
state_transition.pages, state_transition.time_ms
|
||||
);
|
||||
// Truncate the swap file to hold minimum resources while disabled.
|
||||
swap_file.set_len(0).context("clear swap file")?;
|
||||
state = SwapState::Disabled;
|
||||
} else {
|
||||
error!("swap is already disabled.");
|
||||
}
|
||||
state = SwapState::InProgress {
|
||||
direction: SwapDirection::In,
|
||||
started_time: std::time::Instant::now(),
|
||||
};
|
||||
state_transition = StateTransition::default();
|
||||
info!("start swapping in.");
|
||||
}
|
||||
Command::Exit => {
|
||||
break 'wait;
|
||||
|
|
Loading…
Reference in a new issue