Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mmap: try THP via madvise #113

Open
wants to merge 2 commits into
base: v0.2.2_release
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
THP: introduce options
Allow to control whether we will use huge pages via options.

Signed-off-by: Norbert Manthey <nmanthey@amazon.de>
  • Loading branch information
nmanthey committed Nov 19, 2020
commit d97ec75841b6c9556492553e19118426e2476f8f
9 changes: 9 additions & 0 deletions src/guest_memory.rs
Original file line number Diff line number Diff line change
@@ -159,6 +159,15 @@ impl FileOffset {
}
}

/// Configurations options usable for Guest Memory
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd)]
pub struct GuestMemoryOptions {
/// Use huge pages to back guest memory
pub huge_page: bool,
/// Use transparent huge pages to back guest memory
pub transparent_huge_page: bool,
}

/// Represents a continuous region of guest physical memory.
#[allow(clippy::len_without_is_empty)]
pub trait GuestMemoryRegion: Bytes<MemoryRegionAddress, E = Error> {
12 changes: 7 additions & 5 deletions src/mmap.rs
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ use std::sync::Arc;

use crate::address::Address;
use crate::guest_memory::{
self, FileOffset, GuestAddress, GuestMemory, GuestMemoryRegion, GuestUsize, MemoryRegionAddress,
self, FileOffset, GuestAddress, GuestMemory, GuestMemoryOptions, GuestMemoryRegion, GuestUsize, MemoryRegionAddress,
};
use crate::volatile_memory::{VolatileMemory, VolatileSlice};
use crate::Bytes;
@@ -391,6 +391,7 @@ impl GuestMemoryRegion for GuestRegionMmap {
/// virtual address space of the calling process.
#[derive(Clone, Debug, Default)]
pub struct GuestMemoryMmap {
options: GuestMemoryOptions,
regions: Vec<Arc<GuestRegionMmap>>,
}

@@ -416,6 +417,7 @@ impl GuestMemoryMmap {
A: Borrow<(GuestAddress, usize, Option<FileOffset>)>,
T: IntoIterator<Item = A>,
{
let options = GuestMemoryOptions {huge_page : false, transparent_huge_page : false};
Self::from_regions(
ranges
.into_iter()
@@ -424,9 +426,9 @@ impl GuestMemoryMmap {
let size = x.borrow().1;

if let Some(ref f_off) = x.borrow().2 {
MmapRegion::from_file(f_off.clone(), size)
MmapRegion::from_file(f_off.clone(), size, options)
} else {
MmapRegion::new(size)
MmapRegion::new(size, options)
}
.map_err(Error::MmapRegion)
.and_then(|r| GuestRegionMmap::new(r, guest_base))
@@ -476,7 +478,7 @@ impl GuestMemoryMmap {
}
}

Ok(Self { regions })
Ok(Self { regions, options: GuestMemoryOptions {huge_page : false, transparent_huge_page : false} })
}

/// Insert a region into the `GuestMemoryMmap` object and return a new `GuestMemoryMmap`.
@@ -509,7 +511,7 @@ impl GuestMemoryMmap {
if self.regions.get(region_index).unwrap().size() as GuestUsize == size {
let mut regions = self.regions.clone();
let region = regions.remove(region_index);
return Ok((Self { regions }, region));
return Ok((Self { regions, options: GuestMemoryOptions {huge_page : false, transparent_huge_page : false} }, region));
}
}

16 changes: 13 additions & 3 deletions src/mmap_unix.rs
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@ use std::result;
use libc;

use crate::guest_memory::FileOffset;
use crate::guest_memory::GuestMemoryOptions;
use crate::mmap::{check_file_offset, AsSlice};
use crate::volatile_memory::{self, compute_offset, VolatileMemory, VolatileSlice};

@@ -93,12 +94,13 @@ impl MmapRegion {
///
/// # Arguments
/// * `size` - The size of the memory region in bytes.
pub fn new(size: usize) -> Result<Self> {
pub fn new(size: usize, options: GuestMemoryOptions) -> Result<Self> {
Self::build(
None,
size,
libc::PROT_READ | libc::PROT_WRITE,
libc::MAP_ANONYMOUS | libc::MAP_NORESERVE | libc::MAP_PRIVATE,
options
)
}

@@ -108,12 +110,13 @@ impl MmapRegion {
/// * `file_offset` - The mapping will be created at offset `file_offset.start` in the file
/// referred to by `file_offset.file`.
/// * `size` - The size of the memory region in bytes.
pub fn from_file(file_offset: FileOffset, size: usize) -> Result<Self> {
pub fn from_file(file_offset: FileOffset, size: usize, options: GuestMemoryOptions) -> Result<Self> {
Self::build(
Some(file_offset),
size,
libc::PROT_READ | libc::PROT_WRITE,
libc::MAP_NORESERVE | libc::MAP_SHARED,
options
)
}

@@ -132,6 +135,7 @@ impl MmapRegion {
size: usize,
prot: i32,
flags: i32,
options: GuestMemoryOptions,
) -> Result<Self> {
// Forbid MAP_FIXED, as it doesn't make sense in this context, and is pretty dangerous
// in general.
@@ -154,7 +158,13 @@ impl MmapRegion {
return Err(Error::Mmap(io::Error::last_os_error()));
}

let _ret = unsafe { libc::madvise(addr, size, libc::MADV_HUGEPAGE) };
if options.huge_page {
if options.transparent_huge_page {
if size > 2 * 1024 * 4096 {
let _ret = unsafe { libc::madvise(addr, size, libc::MADV_HUGEPAGE) };
}
}
}

Ok(Self {
addr: addr as *mut u8,