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, |     FileBacked, VMInitializer, VMMapAddr, VMMapOptions, VMMapOptionsBuilder, VMRemapOptions, | ||||||
| }; | }; | ||||||
| use std::collections::HashSet; | use std::collections::HashSet; | ||||||
|  | use util::sync::rw_lock::RwLockWriteGuard; | ||||||
| 
 | 
 | ||||||
| // Used for heap and stack start address randomization.
 | // Used for heap and stack start address randomization.
 | ||||||
| const RANGE_FOR_RANDOMIZATION: usize = 256 * 4096; // 1M
 | const RANGE_FOR_RANDOMIZATION: usize = 256 * 4096; // 1M
 | ||||||
| @ -346,9 +347,10 @@ impl ProcessVM { | |||||||
| 
 | 
 | ||||||
|     // Try merging all connecting single VMAs of the process.
 |     // Try merging all connecting single VMAs of the process.
 | ||||||
|     // This is a very expensive operation.
 |     // 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
 |         // Get all single VMA chunks
 | ||||||
|         let mut mem_chunks = self.mem_chunks.write().unwrap(); |  | ||||||
|         let mut single_vma_chunks = mem_chunks |         let mut single_vma_chunks = mem_chunks | ||||||
|             .drain_filter(|chunk| chunk.is_single_vma()) |             .drain_filter(|chunk| chunk.is_single_vma()) | ||||||
|             .collect::<Vec<ChunkRef>>(); |             .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
 |             // 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 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(); |             internal_manager.clean_single_vma_chunks(); | ||||||
|  | 
 | ||||||
|  |             // Add merged chunks to internal manager and process mem_chunks
 | ||||||
|             while merged_vmas.len() != 0 { |             while merged_vmas.len() != 0 { | ||||||
|                 let merged_vma = merged_vmas.pop().unwrap(); |                 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
 |                             // Munmap the corresponding single vma chunk
 | ||||||
|                             // let mut internal_manager = self.internal();
 |  | ||||||
|                             self.munmap_chunk(&chunk, Some(&target_range))?; |                             self.munmap_chunk(&chunk, Some(&target_range))?; | ||||||
|                         } |                         } | ||||||
|                         VMMapAddr::Any => unreachable!(), |                         VMMapAddr::Any => unreachable!(), | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user