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()) | ||||
|     } | ||||
| 
 | ||||
|     // 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); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user