Struct swap::page_handler::PageHandler
source · pub struct PageHandler<'a> {
ctx: Mutex<PageHandleContext<'a>>,
channel: Arc<Channel<MoveToStaging>>,
}
Expand description
PageHandler manages the page states of multiple regions.
Handles multiple events derived from userfaultfd and swap out requests. All the addresses and sizes in bytes are converted to page id internally.
Fields§
§ctx: Mutex<PageHandleContext<'a>>
§channel: Arc<Channel<MoveToStaging>>
Implementations§
source§impl<'a> PageHandler<'a>
impl<'a> PageHandler<'a>
sourcepub fn create(
swap_file: &'a File,
staging_shmem: &'a SharedMemory,
address_ranges: &[Range<usize>],
stating_move_context: Arc<Channel<MoveToStaging>>
) -> Result<Self>
pub fn create( swap_file: &'a File, staging_shmem: &'a SharedMemory, address_ranges: &[Range<usize>], stating_move_context: Arc<Channel<MoveToStaging>> ) -> Result<Self>
Creates PageHandler for the given region.
If any of regions overlaps, this returns Error::RegionOverlap.
§Arguments
swap_file
- The swap file.staging_shmem
- The staging memory. It must have enough size to hold guest memory. Otherwise monitor process crashes on creating a mmap.address_ranges
- The list of address range of the regions. the start address must align with page. the size must be multiple of pagesize.
fn find_region(regions: &mut [Region], page_idx: usize) -> Option<&mut Region>
sourcepub fn handle_page_fault(
&self,
uffd: &Userfaultfd,
address: usize
) -> Result<()>
pub fn handle_page_fault( &self, uffd: &Userfaultfd, address: usize ) -> Result<()>
Fills the faulted page with zero if the page is not initialized, with the content in the swap file if the page is swapped out.
§Arguments
uffd
- the reference to the Userfaultfd for the faulting process.address
- the address that triggered the page fault.
sourcepub fn handle_page_remove(
&self,
start_addr: usize,
end_addr: usize
) -> Result<()>
pub fn handle_page_remove( &self, start_addr: usize, end_addr: usize ) -> Result<()>
Clear the internal state for the pages.
When pages are removed by madvise with MADV_DONTNEED
or MADV_REMOVE
, userfaultfd
notifies the event as UFFD_EVENT_REMOVE
. This handles the remove event.
In crosvm, balloon frees the guest memory and cause UFFD_EVENT_REMOVE
.
§Arguments
start_addr
- the head address of the memory area to be freed.end_addr
- the end address of the memory area to be freed.UFFD_EVENT_REMOVE
tells the head address of the next memory area of the freed area. (i.e. the exact tail address of the memory area isend_addr - 1
.)
sourcepub unsafe fn move_to_staging<T>(
&self,
base_addr: usize,
memfd: &T,
base_offset: u64
) -> Result<usize>where
T: AsRawDescriptor,
pub unsafe fn move_to_staging<T>(
&self,
base_addr: usize,
memfd: &T,
base_offset: u64
) -> Result<usize>where
T: AsRawDescriptor,
Move active pages in the memory region to the staging memory.
It only moves active contents in the guest memory to the swap file and skips empty pages
(e.g. pages not touched, freed by balloon) using lseek(2)
+ SEEK_HOLE/DATA
.
Returns the count of moved out pages.
§Arguments
base_addr
- the head address of the memory region.memfd
- the file descriptor of the memfd backing the guest memory region.base_offset
- the offset of the memory region in the memfd.
§Safety
The region must have been registered to all userfaultfd of processes which may touch the region.
The memory must be protected not to be updated while moving.
The page fault events for the region from the userfaultfd must be handled by Self::handle_page_fault().
Must call Channel::wait_complete() to wait all the copy operation complete within the memory protection period.
sourcepub fn swap_out(&self, max_size: usize) -> Result<usize>
pub fn swap_out(&self, max_size: usize) -> Result<usize>
Write a chunk of consecutive pages in the staging memory to the swap file.
If there is no active pages in the staging memory, this returns Ok(0)
.
The pages in guest memory have been moved to staging memory by Self::move_to_staging().
Returns the count of swapped out pages.
Even if swap_out fails on any internal steps, it does not break the page state management
and PageHandler
can continue working with a little pages leaking in staging memory or swap
file. The leaked pages are removed when vmm-swap is disabled and PageHandler
is dropped.
§Arguments
max_size
- the upper limit of the chunk size to write into the swap file at once. The chunk is splitted if it is bigger thanmax_size
.
sourcepub fn start_swap_in(&'a self) -> SwapInContext<'a>
pub fn start_swap_in(&'a self) -> SwapInContext<'a>
Create a new SwapInContext.
sourcepub fn start_trim(&'a self) -> TrimContext<'a>
pub fn start_trim(&'a self) -> TrimContext<'a>
Create a new TrimContext.
sourcefn compute_copied_from_file_pages(&self) -> usize
fn compute_copied_from_file_pages(&self) -> usize
Returns count of pages copied from vmm-swap file to the guest memory.
sourcefn compute_copied_from_staging_pages(&self) -> usize
fn compute_copied_from_staging_pages(&self) -> usize
Returns count of pages copied from staging memory to the guest memory.
sourcefn compute_zeroed_pages(&self) -> usize
fn compute_zeroed_pages(&self) -> usize
Returns count of pages initialized with zero.
sourcefn compute_redundant_pages(&self) -> usize
fn compute_redundant_pages(&self) -> usize
Returns count of pages which were already initialized on page faults.
sourcefn compute_staging_pages(&self) -> usize
fn compute_staging_pages(&self) -> usize
Returns count of pages present in the staging memory.
sourcefn compute_swap_pages(&self) -> usize
fn compute_swap_pages(&self) -> usize
Returns count of pages present in the swap files.
sourcepub fn load_metrics(&self, metrics: &mut SwapMetrics)
pub fn load_metrics(&self, metrics: &mut SwapMetrics)
Fill SwapMetrics with page handler metrics.