Respect alignment when finding free ranges
This commit is contained in:
parent
56f7ab02a5
commit
94f9ff7814
@ -31,7 +31,6 @@ impl VMFreeSpaceManager {
|
|||||||
.fold(0, |acc, free_range| acc + free_range.size())
|
.fold(0, |acc, free_range| acc + free_range.size())
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: respect options.align when mmap
|
|
||||||
pub fn find_free_range_internal(
|
pub fn find_free_range_internal(
|
||||||
&mut self,
|
&mut self,
|
||||||
size: usize,
|
size: usize,
|
||||||
@ -45,6 +44,15 @@ impl VMFreeSpaceManager {
|
|||||||
|
|
||||||
trace!("find free range, free list = {:?}", free_list);
|
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() {
|
for (idx, free_range) in free_list.iter().enumerate() {
|
||||||
let mut free_range = {
|
let mut free_range = {
|
||||||
if free_range.size() < size {
|
if free_range.size() < size {
|
||||||
@ -55,22 +63,33 @@ impl VMFreeSpaceManager {
|
|||||||
|
|
||||||
match addr {
|
match addr {
|
||||||
// Want a minimal free_range
|
// 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
|
// Prefer to have free_range.start == addr
|
||||||
VMMapAddr::Hint(addr) => {
|
VMMapAddr::Hint(addr) => {
|
||||||
if addr % align == 0
|
if free_range.contains(addr) && free_range.end() - addr >= size {
|
||||||
&& free_range.contains(addr)
|
|
||||||
&& free_range.end() - addr >= size
|
|
||||||
{
|
|
||||||
free_range.start = addr;
|
free_range.start = addr;
|
||||||
free_range.end = addr + size;
|
free_range.end = addr + size;
|
||||||
self.free_list_update_range(idx, free_range);
|
|
||||||
return Ok(free_range);
|
|
||||||
} else {
|
} else {
|
||||||
// Hint failure, record the result but keep iterating.
|
// Hint failure, record the result but keep iterating.
|
||||||
if result_free_range == None
|
if result_free_range == None
|
||||||
|| result_free_range.as_ref().unwrap().size() > free_range.size()
|
|| 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_free_range = Some(free_range);
|
||||||
result_idx = Some(idx);
|
result_idx = Some(idx);
|
||||||
}
|
}
|
||||||
@ -103,15 +122,14 @@ impl VMFreeSpaceManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let index = result_idx.unwrap();
|
let index = result_idx.unwrap();
|
||||||
let result_free_range = {
|
let result_free_range = result_free_range.unwrap();
|
||||||
let free_range = result_free_range.unwrap();
|
|
||||||
let start = align_up(free_range.start(), align);
|
|
||||||
let end = start + size;
|
|
||||||
VMRange { start, end }
|
|
||||||
};
|
|
||||||
|
|
||||||
self.free_list_update_range(index, result_free_range);
|
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);
|
return Ok(result_free_range);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user