diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp index 4009319ae2..47b48a3c6f 100644 --- a/src/system/kernel/vm/vm.cpp +++ b/src/system/kernel/vm/vm.cpp @@ -2570,7 +2570,8 @@ delete_area(VMAddressSpace* addressSpace, VMArea* area, { ASSERT(!area->IsWired()); - VMAreas::Remove(area); + if (area->id >= 0) + VMAreas::Remove(area); // At this point the area is removed from the global hash table, but // still exists in the area list. @@ -3992,6 +3993,17 @@ vm_delete_areas(struct VMAddressSpace* addressSpace, bool deletingAddressSpace) // remove all reserved areas in this address space addressSpace->UnreserveAllAddressRanges(0); + // remove all areas from the areas map at once (to avoid lock contention) + VMAreas::WriteLock(); + { + VMAddressSpace::AreaIterator it = addressSpace->GetAreaIterator(); + while (VMArea* area = it.Next()) { + VMAreas::Remove(area); + area->id = INT32_MIN; + } + } + VMAreas::WriteUnlock(); + // delete all the areas in this address space while (VMArea* area = addressSpace->FirstArea()) { ASSERT(!area->IsWired());