Skip to content

Commit 9428858

Browse files
author
Hui Zhu
committed
Add is_hugetlbfs() to GuestMemoryRegion
Virtio-balloon can release the unused host memory to decrease the memory usage of the VMM. Release normal pages and hugetlbfs pages require different operations. (madvise MADV_DONTNEED and fallocate64 FALLOC_FL_PUNCH_HOLE) This commit add Add is_hugetlbfs() to GuestMemoryRegion to help VMM decide if this is a hugetlbfs address or not. Signed-off-by: Hui Zhu <teawater@antfin.com>
1 parent 54c8934 commit 9428858

File tree

4 files changed

+59
-0
lines changed

4 files changed

+59
-0
lines changed

src/guest_memory.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,11 @@ pub trait GuestMemoryRegion: Bytes<MemoryRegionAddress, E = Error> {
288288
fn as_volatile_slice(&self) -> Result<volatile_memory::VolatileSlice> {
289289
self.get_slice(MemoryRegionAddress(0), self.len() as usize)
290290
}
291+
292+
/// Returns true if the region is hugetlbfs
293+
fn is_hugetlbfs(&self) -> bool {
294+
false
295+
}
291296
}
292297

293298
/// `GuestAddressSpace` provides a way to retrieve a `GuestMemory` object.
@@ -1106,4 +1111,13 @@ mod tests {
11061111

11071112
crate::bytes::tests::check_atomic_accesses(mem, addr, bad_addr);
11081113
}
1114+
1115+
#[cfg(feature = "backend-mmap")]
1116+
#[test]
1117+
fn test_guest_memory_mmap_is_hugetlbfs() {
1118+
let addr = GuestAddress(0x1000);
1119+
let mem = GuestMemoryMmap::from_ranges(&[(addr, 0x1000)]).unwrap();
1120+
let r = mem.find_region(addr).unwrap();
1121+
assert_eq!(r.is_hugetlbfs(), false);
1122+
}
11091123
}

src/mmap.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,10 @@ impl GuestMemoryRegion for GuestRegionMmap {
403403
let slice = self.mapping.get_slice(offset.raw_value() as usize, count)?;
404404
Ok(slice)
405405
}
406+
407+
fn is_hugetlbfs(&self) -> bool {
408+
self.mapping.is_hugetlbfs()
409+
}
406410
}
407411

408412
/// [`GuestMemory`](trait.GuestMemory.html) implementation that mmaps the guest's memory

src/mmap_unix.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,11 @@ impl MmapRegion {
272272
}
273273
false
274274
}
275+
276+
/// Returns `true` if the region is hugetlbfs
277+
pub fn is_hugetlbfs(&self) -> bool {
278+
(self.flags & libc::MAP_HUGETLB) != 0
279+
}
275280
}
276281

277282
impl AsSlice for MmapRegion {
@@ -327,6 +332,9 @@ mod tests {
327332
use std::sync::Arc;
328333
use vmm_sys_util::tempfile::TempFile;
329334

335+
use std::ffi;
336+
use std::{fs::File, os::unix::io::FromRawFd};
337+
330338
// Adding a helper method to extract the errno within an Error::Mmap(e), or return a
331339
// distinctive value when the error is represented by another variant.
332340
impl Error {
@@ -354,6 +362,34 @@ mod tests {
354362
);
355363
}
356364

365+
#[test]
366+
fn test_mmap_region_is_hugetlbfs() {
367+
let r = MmapRegion::new(4096).unwrap();
368+
assert_eq!(r.is_hugetlbfs(), false);
369+
370+
let res = unsafe {
371+
libc::syscall(
372+
libc::SYS_memfd_create,
373+
&ffi::CString::new("ch_ram").unwrap(),
374+
libc::MFD_HUGETLB | libc::MAP_HUGE_2MB as u32,
375+
)
376+
};
377+
if res < 0 {
378+
/* Linux kernel version older than 4.16 doesn't support MFD_HUGETLB */
379+
return;
380+
}
381+
let f = unsafe { File::from_raw_fd(res as i32) };
382+
f.set_len(2 * 1024 * 1024).unwrap();
383+
let r = MmapRegion::build(
384+
Some(FileOffset::new(f, 0)),
385+
2 * 1024 * 1024,
386+
libc::PROT_READ | libc::PROT_WRITE,
387+
libc::MAP_NORESERVE | libc::MAP_PRIVATE | libc::MAP_HUGETLB,
388+
)
389+
.unwrap();
390+
assert_eq!(r.is_hugetlbfs(), true);
391+
}
392+
357393
#[test]
358394
fn test_mmap_region_from_file() {
359395
let mut f = TempFile::new().unwrap().into_file();

src/mmap_windows.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,11 @@ impl MmapRegion {
175175
pub fn file_offset(&self) -> Option<&FileOffset> {
176176
self.file_offset.as_ref()
177177
}
178+
179+
/// Windows doesn't have hugetlbfs.
180+
pub fn is_hugetlbfs(&self) -> bool {
181+
false
182+
}
178183
}
179184

180185
impl AsSlice for MmapRegion {

0 commit comments

Comments
 (0)