mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2024-12-26 13:10:56 +00:00
sys_util: Add ability to madvise a region
Add functions to let the kernel know a given range of memory isn't needed currently. This function will result in `madvise(DONTNEED)`. The ability to signal memory as not needed will be used by the balloon driver to allow system memory to be redistributed away from the VM. Change-Id: I4ca56e09010eec33989824f5738db4a4be0ec428 Signed-off-by: Dylan Reid <dgreid@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/759305 Reviewed-by: Zach Reizner <zachr@chromium.org>
This commit is contained in:
parent
fedb675ed5
commit
2415ef6988
2 changed files with 32 additions and 0 deletions
|
@ -105,6 +105,15 @@ impl GuestMemory {
|
|||
self.regions.len()
|
||||
}
|
||||
|
||||
/// Madvise away the address range in the host that is associated with the given guest range.
|
||||
pub fn dont_need_range(&self, addr: GuestAddress, count: usize) -> Result<()> {
|
||||
self.do_in_region(addr, move |mapping, offset| {
|
||||
mapping
|
||||
.dont_need_range(offset, count)
|
||||
.map_err(|e| Error::MemoryAccess(addr, e))
|
||||
})
|
||||
}
|
||||
|
||||
/// Perform the specified action on each region's addresses.
|
||||
pub fn with_regions<F, E>(&self, cb: F) -> result::Result<(), E>
|
||||
where F: Fn(usize, GuestAddress, usize, usize) -> result::Result<(), E>
|
||||
|
|
|
@ -299,6 +299,29 @@ impl MemoryMapping {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Uses madvise to tell the kernel the specified range won't be needed soon.
|
||||
pub fn dont_need_range(&self, mem_offset: usize, count: usize) -> Result<()> {
|
||||
let mem_end = match mem_offset.checked_add(count) {
|
||||
None => return Err(Error::InvalidRange(mem_offset, count)),
|
||||
Some(m) => m,
|
||||
};
|
||||
if mem_end > self.size() {
|
||||
return Err(Error::InvalidRange(mem_offset, count));
|
||||
}
|
||||
let ret = unsafe {
|
||||
// madvising away the region is the same as the guest changing it.
|
||||
// Next time it is read, it may return zero pages.
|
||||
libc::madvise((self.addr as usize + mem_offset) as *mut _,
|
||||
count,
|
||||
libc::MADV_DONTNEED)
|
||||
};
|
||||
if ret < 0 {
|
||||
Err(Error::InvalidRange(mem_offset, count))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn as_slice(&self) -> &[u8] {
|
||||
// This is safe because we mapped the area at addr ourselves, so this slice will not
|
||||
// overflow. However, it is possible to alias.
|
||||
|
|
Loading…
Reference in a new issue