Fix mremap lock range when merging connecting chunks

This commit is contained in:
Hui, Chunyang 2023-01-30 16:39:15 +08:00 committed by volcano
parent 28fb6fd767
commit 6107a32675
2 changed files with 14 additions and 5 deletions

@ -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(&current, 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!(),