Skip to content

Commit 1dd3577

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 requiring 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. It returns None represents that no information is available. Signed-off-by: Hui Zhu <teawater@antfin.com>
1 parent 6a0dcc1 commit 1dd3577

File tree

4 files changed

+85
-0
lines changed

4 files changed

+85
-0
lines changed

src/guest_memory.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,33 @@ 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+
/// Show if the region is based on the `HugeTLBFS`.
293+
/// Returns Some(true) if the region is backed by hugetlbfs.
294+
/// None represents that no information is available.
295+
///
296+
/// # Examples
297+
///
298+
/// ```
299+
/// # #[cfg(feature = "backend-mmap")]
300+
/// # use vm_memory::{GuestAddress, GuestMemory, GuestMemoryMmap, GuestRegionMmap};
301+
///
302+
/// # #[cfg(feature = "backend-mmap")]
303+
/// # fn test_guest_memory_mmap_is_hugetlbfs() {
304+
/// let addr = GuestAddress(0x1000);
305+
/// let mem = GuestMemoryMmap::from_ranges(&[(addr, 0x1000)]).unwrap();
306+
/// let r = mem.find_region(addr).unwrap();
307+
/// # #[cfg(all(feature = "backend-mmap", unix))]
308+
/// assert_eq!(r.is_hugetlbfs(), Some(false));
309+
/// # #[cfg(all(feature = "backend-mmap", windows))]
310+
/// assert_eq!(r.is_hugetlbfs(), None);
311+
/// # }
312+
/// # #[cfg(feature = "backend-mmap")]
313+
/// # test_guest_memory_mmap_is_hugetlbfs();
314+
/// ```
315+
fn is_hugetlbfs(&self) -> Option<bool> {
316+
None
317+
}
291318
}
292319

293320
/// `GuestAddressSpace` provides a way to retrieve a `GuestMemory` object.
@@ -1170,4 +1197,22 @@ mod tests {
11701197

11711198
crate::bytes::tests::check_atomic_accesses(mem, addr, bad_addr);
11721199
}
1200+
1201+
#[cfg(all(feature = "backend-mmap", unix))]
1202+
#[test]
1203+
fn test_guest_memory_mmap_is_hugetlbfs_unix() {
1204+
let addr = GuestAddress(0x1000);
1205+
let mem = GuestMemoryMmap::from_ranges(&[(addr, 0x1000)]).unwrap();
1206+
let r = mem.find_region(addr).unwrap();
1207+
assert_eq!(r.is_hugetlbfs(), Some(false));
1208+
}
1209+
1210+
#[cfg(all(feature = "backend-mmap", windows))]
1211+
#[test]
1212+
fn test_guest_memory_mmap_is_hugetlbfs_windows() {
1213+
let addr = GuestAddress(0x1000);
1214+
let mem = GuestMemoryMmap::from_ranges(&[(addr, 0x1000)]).unwrap();
1215+
let r = mem.find_region(addr).unwrap();
1216+
assert_eq!(r.is_hugetlbfs(), None);
1217+
}
11731218
}

src/mmap.rs

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

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

src/mmap_unix.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ pub struct MmapRegion {
9090
prot: i32,
9191
flags: i32,
9292
owned: bool,
93+
hugetlbfs: bool,
9394
}
9495

9596
// Send and Sync aren't automatically inherited for the raw address pointer.
@@ -172,6 +173,7 @@ impl MmapRegion {
172173
prot,
173174
flags,
174175
owned: true,
176+
hugetlbfs: false,
175177
})
176178
}
177179

@@ -213,6 +215,7 @@ impl MmapRegion {
213215
prot,
214216
flags,
215217
owned: false,
218+
hugetlbfs: false,
216219
})
217220
}
218221

@@ -272,6 +275,16 @@ impl MmapRegion {
272275
}
273276
false
274277
}
278+
279+
/// Set the hugetlbfs of the region
280+
pub fn set_hugetlbfs(&mut self, hugetlbfs: bool) {
281+
self.hugetlbfs = hugetlbfs
282+
}
283+
284+
/// Returns `true` if the region is hugetlbfs
285+
pub fn is_hugetlbfs(&self) -> Option<bool> {
286+
Some(self.hugetlbfs)
287+
}
275288
}
276289

277290
impl AsSlice for MmapRegion {
@@ -354,6 +367,24 @@ mod tests {
354367
);
355368
}
356369

370+
#[test]
371+
fn test_mmap_region_set_hugetlbfs() {
372+
assert!(MmapRegion::new(0).is_err());
373+
374+
let size = 4096;
375+
376+
let mut r = MmapRegion::new(4096).unwrap();
377+
r.set_hugetlbfs(true);
378+
assert_eq!(r.size(), size);
379+
assert!(r.file_offset().is_none());
380+
assert_eq!(r.prot(), libc::PROT_READ | libc::PROT_WRITE);
381+
assert_eq!(
382+
r.flags(),
383+
libc::MAP_ANONYMOUS | libc::MAP_NORESERVE | libc::MAP_PRIVATE
384+
);
385+
assert_eq!(r.is_hugetlbfs(), Some(true));
386+
}
387+
357388
#[test]
358389
fn test_mmap_region_from_file() {
359390
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) -> Option<bool> {
181+
None
182+
}
178183
}
179184

180185
impl AsSlice for MmapRegion {

0 commit comments

Comments
 (0)