Respect alignment when finding free ranges

This commit is contained in:
Hui, Chunyang 2023-08-29 08:08:00 +00:00 committed by volcano
parent 56f7ab02a5
commit 94f9ff7814

@ -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);
}