Skip to content

Commit e63914e

Browse files
Hui Zhujiangliu
Hui Zhu
authored andcommitted
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 <[email protected]>
1 parent 576a406 commit e63914e

File tree

4 files changed

+90
-0
lines changed

4 files changed

+90
-0
lines changed

src/guest_memory.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,26 @@ pub trait GuestMemoryRegion: Bytes<MemoryRegionAddress, E = Error> {
289289
fn as_volatile_slice(&self) -> Result<volatile_memory::VolatileSlice> {
290290
self.get_slice(MemoryRegionAddress(0), self.len() as usize)
291291
}
292+
293+
/// Show if the region is based on the `HugeTLBFS`.
294+
/// Returns Some(true) if the region is backed by hugetlbfs.
295+
/// None represents that no information is available.
296+
///
297+
/// # Examples (uses the `backend-mmap` feature)
298+
///
299+
/// ```
300+
/// # #[cfg(feature = "backend-mmap")]
301+
/// # {
302+
/// # use vm_memory::{GuestAddress, GuestMemory, GuestMemoryMmap, GuestRegionMmap};
303+
/// let addr = GuestAddress(0x1000);
304+
/// let mem = GuestMemoryMmap::from_ranges(&[(addr, 0x1000)]).unwrap();
305+
/// let r = mem.find_region(addr).unwrap();
306+
/// assert_eq!(r.is_hugetlbfs(), None);
307+
/// # }
308+
/// ```
309+
fn is_hugetlbfs(&self) -> Option<bool> {
310+
None
311+
}
292312
}
293313

294314
/// `GuestAddressSpace` provides a way to retrieve a `GuestMemory` object.
@@ -1199,4 +1219,13 @@ mod tests {
11991219

12001220
crate::bytes::tests::check_atomic_accesses(mem, addr, bad_addr);
12011221
}
1222+
1223+
#[cfg(feature = "backend-mmap")]
1224+
#[test]
1225+
fn test_guest_memory_mmap_is_hugetlbfs() {
1226+
let addr = GuestAddress(0x1000);
1227+
let mem = GuestMemoryMmap::from_ranges(&[(addr, 0x1000)]).unwrap();
1228+
let r = mem.find_region(addr).unwrap();
1229+
assert_eq!(r.is_hugetlbfs(), None);
1230+
}
12021231
}

src/mmap.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,10 @@ impl GuestMemoryRegion for GuestRegionMmap {
456456
let slice = self.mapping.get_slice(offset.raw_value() as usize, count)?;
457457
Ok(slice)
458458
}
459+
460+
fn is_hugetlbfs(&self) -> Option<bool> {
461+
self.mapping.is_hugetlbfs()
462+
}
459463
}
460464

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

src/mmap_unix.rs

Lines changed: 52 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: Option<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: None,
175177
})
176178
}
177179

@@ -213,6 +215,7 @@ impl MmapRegion {
213215
prot,
214216
flags,
215217
owned: false,
218+
hugetlbfs: None,
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 = Some(hugetlbfs)
282+
}
283+
284+
/// Returns `true` if the region is hugetlbfs
285+
pub fn is_hugetlbfs(&self) -> Option<bool> {
286+
self.hugetlbfs
287+
}
275288
}
276289

277290
impl AsSlice for MmapRegion {
@@ -354,6 +367,45 @@ 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 r = MmapRegion::new(size).unwrap();
377+
assert_eq!(r.size(), size);
378+
assert!(r.file_offset().is_none());
379+
assert_eq!(r.prot(), libc::PROT_READ | libc::PROT_WRITE);
380+
assert_eq!(
381+
r.flags(),
382+
libc::MAP_ANONYMOUS | libc::MAP_NORESERVE | libc::MAP_PRIVATE
383+
);
384+
assert_eq!(r.is_hugetlbfs(), None);
385+
386+
let mut r = MmapRegion::new(size).unwrap();
387+
r.set_hugetlbfs(false);
388+
assert_eq!(r.size(), size);
389+
assert!(r.file_offset().is_none());
390+
assert_eq!(r.prot(), libc::PROT_READ | libc::PROT_WRITE);
391+
assert_eq!(
392+
r.flags(),
393+
libc::MAP_ANONYMOUS | libc::MAP_NORESERVE | libc::MAP_PRIVATE
394+
);
395+
assert_eq!(r.is_hugetlbfs(), Some(false));
396+
397+
let mut r = MmapRegion::new(size).unwrap();
398+
r.set_hugetlbfs(true);
399+
assert_eq!(r.size(), size);
400+
assert!(r.file_offset().is_none());
401+
assert_eq!(r.prot(), libc::PROT_READ | libc::PROT_WRITE);
402+
assert_eq!(
403+
r.flags(),
404+
libc::MAP_ANONYMOUS | libc::MAP_NORESERVE | libc::MAP_PRIVATE
405+
);
406+
assert_eq!(r.is_hugetlbfs(), Some(true));
407+
}
408+
357409
#[test]
358410
fn test_mmap_region_from_file() {
359411
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+
/// This information is not available on Windows platforms.
180+
pub fn is_hugetlbfs(&self) -> Option<bool> {
181+
None
182+
}
178183
}
179184

180185
impl AsSlice for MmapRegion {

0 commit comments

Comments
 (0)