From 94f9ff78141d8843dd307a8b523a53899f1a49d9 Mon Sep 17 00:00:00 2001 From: "Hui, Chunyang" Date: Tue, 29 Aug 2023 08:08:00 +0000 Subject: [PATCH] Respect alignment when finding free ranges --- src/libos/src/vm/free_space_manager.rs | 48 ++++++++++++++++++-------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/src/libos/src/vm/free_space_manager.rs b/src/libos/src/vm/free_space_manager.rs index 7457b311..2486e6f4 100644 --- a/src/libos/src/vm/free_space_manager.rs +++ b/src/libos/src/vm/free_space_manager.rs @@ -31,7 +31,6 @@ impl VMFreeSpaceManager { .fold(0, |acc, free_range| acc + free_range.size()) } - // TODO: respect options.align when mmap pub fn find_free_range_internal( &mut self, size: usize, @@ -45,6 +44,15 @@ impl VMFreeSpaceManager { trace!("find free range, free list = {:?}", free_list); + match addr { + VMMapAddr::Any => {} + VMMapAddr::Hint(addr) | VMMapAddr::Need(addr) | VMMapAddr::Force(addr) => { + if addr % align != 0 { + return_errno!(EINVAL, "user-provided address is not well-aligned"); + } + } + } + for (idx, free_range) in free_list.iter().enumerate() { let mut free_range = { if free_range.size() < size { @@ -55,22 +63,33 @@ impl VMFreeSpaceManager { match addr { // Want a minimal free_range - VMMapAddr::Any => {} + VMMapAddr::Any => { + let start = align_up(free_range.start(), align); + let end = start + size; + if end > free_range.end() { + continue; + } + free_range.start = start; + free_range.end = end; + } // Prefer to have free_range.start == addr VMMapAddr::Hint(addr) => { - if addr % align == 0 - && free_range.contains(addr) - && free_range.end() - addr >= size - { + if free_range.contains(addr) && free_range.end() - addr >= size { free_range.start = addr; free_range.end = addr + size; - self.free_list_update_range(idx, free_range); - return Ok(free_range); } else { // Hint failure, record the result but keep iterating. if result_free_range == None || result_free_range.as_ref().unwrap().size() > free_range.size() { + let start = align_up(free_range.start(), align); + let end = start + size; + if end > free_range.end() { + continue; + } + free_range.start = start; + free_range.end = end; + result_free_range = Some(free_range); result_idx = Some(idx); } @@ -103,15 +122,14 @@ impl VMFreeSpaceManager { } let index = result_idx.unwrap(); - let result_free_range = { - let free_range = result_free_range.unwrap(); - let start = align_up(free_range.start(), align); - let end = start + size; - VMRange { start, end } - }; + let result_free_range = result_free_range.unwrap(); self.free_list_update_range(index, result_free_range); - trace!("after find free range, free list = {:?}", self.free_manager); + trace!( + "result free range = {:?}. After find free range, free list = {:?}", + result_free_range, + self.free_manager + ); return Ok(result_free_range); }