Fix mremap lock range when merging connecting chunks
This commit is contained in:
		
							parent
							
								
									28fb6fd767
								
							
						
					
					
						commit
						6107a32675
					
				| @ -11,6 +11,7 @@ use super::vm_util::{ | ||||
|     FileBacked, VMInitializer, VMMapAddr, VMMapOptions, VMMapOptionsBuilder, VMRemapOptions, | ||||
| }; | ||||
| use std::collections::HashSet; | ||||
| use util::sync::rw_lock::RwLockWriteGuard; | ||||
| 
 | ||||
| // Used for heap and stack start address randomization.
 | ||||
| const RANGE_FOR_RANDOMIZATION: usize = 256 * 4096; // 1M
 | ||||
| @ -346,9 +347,10 @@ impl ProcessVM { | ||||
| 
 | ||||
|     // Try merging all connecting single VMAs of the process.
 | ||||
|     // This is a very expensive operation.
 | ||||
|     pub fn merge_all_single_vma_chunks(&self) -> Result<Vec<VMArea>> { | ||||
|     pub fn merge_all_single_vma_chunks( | ||||
|         mem_chunks: &mut RwLockWriteGuard<HashSet<ChunkRef>>, | ||||
|     ) -> Result<Vec<VMArea>> { | ||||
|         // Get all single VMA chunks
 | ||||
|         let mut mem_chunks = self.mem_chunks.write().unwrap(); | ||||
|         let mut single_vma_chunks = mem_chunks | ||||
|             .drain_filter(|chunk| chunk.is_single_vma()) | ||||
|             .collect::<Vec<ChunkRef>>(); | ||||
|  | ||||
| @ -392,11 +392,19 @@ impl VMManager { | ||||
|         { | ||||
|             // Must lock the internal manager first here in case the chunk's range and vma are conflict when other threads are operating the VM
 | ||||
|             let mut internal_manager = self.internal.lock().unwrap(); | ||||
|             let mut merged_vmas = current.vm().merge_all_single_vma_chunks()?; | ||||
|             // Lock process mem_chunks during the whole merging process to avoid conflict
 | ||||
|             let mut process_mem_chunks = current.vm().mem_chunks().write().unwrap(); | ||||
| 
 | ||||
|             let mut merged_vmas = ProcessVM::merge_all_single_vma_chunks(&mut process_mem_chunks)?; | ||||
|             internal_manager.clean_single_vma_chunks(); | ||||
| 
 | ||||
|             // Add merged chunks to internal manager and process mem_chunks
 | ||||
|             while merged_vmas.len() != 0 { | ||||
|                 let merged_vma = merged_vmas.pop().unwrap(); | ||||
|                 internal_manager.add_new_chunk(¤t, merged_vma); | ||||
|                 let new_vma_chunk = Arc::new(Chunk::new_chunk_with_vma(merged_vma)); | ||||
|                 let success = internal_manager.chunks.insert(new_vma_chunk.clone()); | ||||
|                 process_mem_chunks.insert(new_vma_chunk); | ||||
|                 debug_assert!(success); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| @ -845,7 +853,6 @@ impl InternalVMManager { | ||||
|                             } | ||||
| 
 | ||||
|                             // Munmap the corresponding single vma chunk
 | ||||
|                             // let mut internal_manager = self.internal();
 | ||||
|                             self.munmap_chunk(&chunk, Some(&target_range))?; | ||||
|                         } | ||||
|                         VMMapAddr::Any => unreachable!(), | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user