From c5874ee4286fb9027cac74ca5fa65f0275489114 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Thu, 26 Dec 2024 20:41:02 -0500 Subject: [PATCH] kernel/vm: Make use of VMTranslationMap::PageUnmapped in UnmapPages. An extra argument is added to allow the VMAreaMappings objects to be added to a queue instead of freed directly (and the lock unlocked, and so on.) All architectures adjusted. This means there is now only one place in each TranslationMap that the page state and other data is directly adjusted (in UnmapArea). Change-Id: I3ed2d6d969d1b1e235144a1035c90c750779af27 Reviewed-on: https://review.haiku-os.org/c/haiku/+/8716 Tested-by: Commit checker robot Reviewed-by: X512 X512 Reviewed-by: waddlesplash --- headers/private/kernel/vm/VMTranslationMap.h | 3 +- .../paging/32bit/ARMVMTranslationMap32Bit.cpp | 51 ++----------------- .../arch/arm64/VMSAv8TranslationMap.cpp | 47 ++--------------- .../paging/040/M68KVMTranslationMap040.cpp | 51 ++----------------- .../ppc/paging/460/PPCVMTranslationMap460.cpp | 51 ++----------------- .../classic/PPCVMTranslationMapClassic.cpp | 51 ++----------------- .../arch/riscv64/RISCV64VMTranslationMap.cpp | 45 +--------------- .../paging/32bit/X86VMTranslationMap32Bit.cpp | 51 ++----------------- .../paging/64bit/X86VMTranslationMap64Bit.cpp | 51 ++----------------- .../x86/paging/pae/X86VMTranslationMapPAE.cpp | 51 ++----------------- src/system/kernel/vm/VMTranslationMap.cpp | 34 ++++++++++--- 11 files changed, 70 insertions(+), 416 deletions(-) diff --git a/headers/private/kernel/vm/VMTranslationMap.h b/headers/private/kernel/vm/VMTranslationMap.h index e4396afb21..2a29e0685f 100644 --- a/headers/private/kernel/vm/VMTranslationMap.h +++ b/headers/private/kernel/vm/VMTranslationMap.h @@ -84,7 +84,8 @@ public: protected: void PageUnmapped(VMArea* area, page_num_t pageNumber, bool accessed, - bool modified, bool updatePageQueue); + bool modified, bool updatePageQueue, + VMAreaMappings* mappingsQueue = NULL); void UnaccessedPageUnmapped(VMArea* area, page_num_t pageNumber); diff --git a/src/system/kernel/arch/arm/paging/32bit/ARMVMTranslationMap32Bit.cpp b/src/system/kernel/arch/arm/paging/32bit/ARMVMTranslationMap32Bit.cpp index 54946f9be2..ca52197ddd 100644 --- a/src/system/kernel/arch/arm/paging/32bit/ARMVMTranslationMap32Bit.cpp +++ b/src/system/kernel/arch/arm/paging/32bit/ARMVMTranslationMap32Bit.cpp @@ -452,52 +452,11 @@ ARMVMTranslationMap32Bit::UnmapPages(VMArea* area, addr_t base, size_t size, } if (area->cache_type != CACHE_TYPE_DEVICE) { - // get the page - vm_page* page = vm_lookup_page( - (oldEntry & ARM_PTE_ADDRESS_MASK) / B_PAGE_SIZE); - ASSERT(page != NULL); - - DEBUG_PAGE_ACCESS_START(page); - - // transfer the accessed/dirty flags to the page - if ((oldEntry & ARM_MMU_L2_FLAG_AP0) != 0) - page->accessed = true; - if ((oldEntry & ARM_MMU_L2_FLAG_AP2) == 0) - page->modified = true; - - // remove the mapping object/decrement the wired_count of the - // page - if (area->wiring == B_NO_LOCK) { - vm_page_mapping* mapping = NULL; - vm_page_mappings::Iterator iterator - = page->mappings.GetIterator(); - while ((mapping = iterator.Next()) != NULL) { - if (mapping->area == area) - break; - } - - ASSERT(mapping != NULL); - - area->mappings.Remove(mapping); - page->mappings.Remove(mapping); - queue.Add(mapping); - } else - page->DecrementWiredCount(); - - if (!page->IsMapped()) { - atomic_add(&gMappedPagesCount, -1); - - if (updatePageQueue) { - if (page->Cache()->temporary) - vm_page_set_state(page, PAGE_STATE_INACTIVE); - else if (page->modified) - vm_page_set_state(page, PAGE_STATE_MODIFIED); - else - vm_page_set_state(page, PAGE_STATE_CACHED); - } - } - - DEBUG_PAGE_ACCESS_END(page); + page_num_t page = (oldEntry & ARM_PTE_ADDRESS_MASK) / B_PAGE_SIZE; + PageUnmapped(area, page, + (oldEntry & ARM_MMU_L2_FLAG_AP0) != 0, + (oldEntry & ARM_MMU_L2_FLAG_AP2) != 0, + updatePageQueue, &queue); } } diff --git a/src/system/kernel/arch/arm64/VMSAv8TranslationMap.cpp b/src/system/kernel/arch/arm64/VMSAv8TranslationMap.cpp index 47339f867e..9f5fa63b7b 100644 --- a/src/system/kernel/arch/arm64/VMSAv8TranslationMap.cpp +++ b/src/system/kernel/arch/arm64/VMSAv8TranslationMap.cpp @@ -681,49 +681,10 @@ VMSAv8TranslationMap::UnmapPages(VMArea* area, addr_t address, size_t size, bool if (area->cache_type == CACHE_TYPE_DEVICE) return; - // get the page - vm_page* page = vm_lookup_page((oldPte & kPteAddrMask) >> fPageBits); - ASSERT(page != NULL); - - DEBUG_PAGE_ACCESS_START(page); - - // transfer the accessed/dirty flags to the page - page->accessed = is_pte_accessed(oldPte); - page->modified = is_pte_dirty(oldPte); - - // remove the mapping object/decrement the wired_count of the - // page - if (area->wiring == B_NO_LOCK) { - vm_page_mapping* mapping = NULL; - vm_page_mappings::Iterator iterator - = page->mappings.GetIterator(); - while ((mapping = iterator.Next()) != NULL) { - if (mapping->area == area) - break; - } - - ASSERT(mapping != NULL); - - area->mappings.Remove(mapping); - page->mappings.Remove(mapping); - queue.Add(mapping); - } else - page->DecrementWiredCount(); - - if (!page->IsMapped()) { - atomic_add(&gMappedPagesCount, -1); - - if (updatePageQueue) { - if (page->Cache()->temporary) - vm_page_set_state(page, PAGE_STATE_INACTIVE); - else if (page->modified) - vm_page_set_state(page, PAGE_STATE_MODIFIED); - else - vm_page_set_state(page, PAGE_STATE_CACHED); - } - } - - DEBUG_PAGE_ACCESS_END(page); + page_num_t page = (oldPte & kPteAddrMask) >> fPageBits; + PageUnmapped(area, page, + is_pte_accessed(oldPte), is_pte_dirty(oldPte), + updatePageQueue, &queue); }); // TODO: As in UnmapPage() we can lose page dirty flags here. ATM it's not diff --git a/src/system/kernel/arch/m68k/paging/040/M68KVMTranslationMap040.cpp b/src/system/kernel/arch/m68k/paging/040/M68KVMTranslationMap040.cpp index 90b871649e..7d7239285a 100644 --- a/src/system/kernel/arch/m68k/paging/040/M68KVMTranslationMap040.cpp +++ b/src/system/kernel/arch/m68k/paging/040/M68KVMTranslationMap040.cpp @@ -573,52 +573,11 @@ M68KVMTranslationMap040::UnmapPages(VMArea* area, addr_t base, size_t size, } if (area->cache_type != CACHE_TYPE_DEVICE) { - // get the page - vm_page* page = vm_lookup_page( - (oldEntry & M68K_PTE_ADDRESS_MASK) / B_PAGE_SIZE); - ASSERT(page != NULL); - - DEBUG_PAGE_ACCESS_START(page); - - // transfer the accessed/dirty flags to the page - if ((oldEntry & M68K_PTE_ACCESSED) != 0) - page->accessed = true; - if ((oldEntry & M68K_PTE_DIRTY) != 0) - page->modified = true; - - // remove the mapping object/decrement the wired_count of the - // page - if (area->wiring == B_NO_LOCK) { - vm_page_mapping* mapping = NULL; - vm_page_mappings::Iterator iterator - = page->mappings.GetIterator(); - while ((mapping = iterator.Next()) != NULL) { - if (mapping->area == area) - break; - } - - ASSERT(mapping != NULL); - - area->mappings.Remove(mapping); - page->mappings.Remove(mapping); - queue.Add(mapping); - } else - page->DecrementWiredCount(); - - if (!page->IsMapped()) { - atomic_add(&gMappedPagesCount, -1); - - if (updatePageQueue) { - if (page->Cache()->temporary) - vm_page_set_state(page, PAGE_STATE_INACTIVE); - else if (page->modified) - vm_page_set_state(page, PAGE_STATE_MODIFIED); - else - vm_page_set_state(page, PAGE_STATE_CACHED); - } - } - - DEBUG_PAGE_ACCESS_END(page); + page_num_t page = (oldEntry & M68K_PTE_ADDRESS_MASK) / B_PAGE_SIZE; + PageUnmapped(area, page, + (oldEntry & M68K_PTE_ACCESSED) != 0, + (oldEntry & M68K_PTE_DIRTY) != 0, + updatePageQueue, &queue); } } diff --git a/src/system/kernel/arch/ppc/paging/460/PPCVMTranslationMap460.cpp b/src/system/kernel/arch/ppc/paging/460/PPCVMTranslationMap460.cpp index bf6549c2a8..d379e94642 100644 --- a/src/system/kernel/arch/ppc/paging/460/PPCVMTranslationMap460.cpp +++ b/src/system/kernel/arch/ppc/paging/460/PPCVMTranslationMap460.cpp @@ -798,52 +798,11 @@ PPCVMTranslationMap460::UnmapPages(VMArea* area, addr_t base, size_t size, } if (area->cache_type != CACHE_TYPE_DEVICE) { - // get the page - vm_page* page = vm_lookup_page( - (oldEntry & PPC_PTE_ADDRESS_MASK) / B_PAGE_SIZE); - ASSERT(page != NULL); - - DEBUG_PAGE_ACCESS_START(page); - - // transfer the accessed/dirty flags to the page - if ((oldEntry & PPC_PTE_ACCESSED) != 0) - page->accessed = true; - if ((oldEntry & PPC_PTE_DIRTY) != 0) - page->modified = true; - - // remove the mapping object/decrement the wired_count of the - // page - if (area->wiring == B_NO_LOCK) { - vm_page_mapping* mapping = NULL; - vm_page_mappings::Iterator iterator - = page->mappings.GetIterator(); - while ((mapping = iterator.Next()) != NULL) { - if (mapping->area == area) - break; - } - - ASSERT(mapping != NULL); - - area->mappings.Remove(mapping); - page->mappings.Remove(mapping); - queue.Add(mapping); - } else - page->DecrementWiredCount(); - - if (!page->IsMapped()) { - atomic_add(&gMappedPagesCount, -1); - - if (updatePageQueue) { - if (page->Cache()->temporary) - vm_page_set_state(page, PAGE_STATE_INACTIVE); - else if (page->modified) - vm_page_set_state(page, PAGE_STATE_MODIFIED); - else - vm_page_set_state(page, PAGE_STATE_CACHED); - } - } - - DEBUG_PAGE_ACCESS_END(page); + page_num_t page = (oldEntry & PPC_PTE_ADDRESS_MASK) / B_PAGE_SIZE; + PageUnmapped(area, page, + (oldEntry & PPC_PTE_ACCESSED) != 0, + (oldEntry & PPC_PTE_DIRTY) != 0, + updatePageQueue, &queue); } } diff --git a/src/system/kernel/arch/ppc/paging/classic/PPCVMTranslationMapClassic.cpp b/src/system/kernel/arch/ppc/paging/classic/PPCVMTranslationMapClassic.cpp index 6cb83f7790..e9918c3296 100644 --- a/src/system/kernel/arch/ppc/paging/classic/PPCVMTranslationMapClassic.cpp +++ b/src/system/kernel/arch/ppc/paging/classic/PPCVMTranslationMapClassic.cpp @@ -798,52 +798,11 @@ PPCVMTranslationMapClassic::UnmapPages(VMArea* area, addr_t base, size_t size, } if (area->cache_type != CACHE_TYPE_DEVICE) { - // get the page - vm_page* page = vm_lookup_page( - (oldEntry & PPC_PTE_ADDRESS_MASK) / B_PAGE_SIZE); - ASSERT(page != NULL); - - DEBUG_PAGE_ACCESS_START(page); - - // transfer the accessed/dirty flags to the page - if ((oldEntry & PPC_PTE_ACCESSED) != 0) - page->accessed = true; - if ((oldEntry & PPC_PTE_DIRTY) != 0) - page->modified = true; - - // remove the mapping object/decrement the wired_count of the - // page - if (area->wiring == B_NO_LOCK) { - vm_page_mapping* mapping = NULL; - vm_page_mappings::Iterator iterator - = page->mappings.GetIterator(); - while ((mapping = iterator.Next()) != NULL) { - if (mapping->area == area) - break; - } - - ASSERT(mapping != NULL); - - area->mappings.Remove(mapping); - page->mappings.Remove(mapping); - queue.Add(mapping); - } else - page->DecrementWiredCount(); - - if (!page->IsMapped()) { - atomic_add(&gMappedPagesCount, -1); - - if (updatePageQueue) { - if (page->Cache()->temporary) - vm_page_set_state(page, PAGE_STATE_INACTIVE); - else if (page->modified) - vm_page_set_state(page, PAGE_STATE_MODIFIED); - else - vm_page_set_state(page, PAGE_STATE_CACHED); - } - } - - DEBUG_PAGE_ACCESS_END(page); + page_num_t page = (oldEntry & PPC_PTE_ADDRESS_MASK) / B_PAGE_SIZE; + PageUnmapped(area, page, + (oldEntry & PPC_PTE_ACCESSED) != 0, + (oldEntry & PPC_PTE_DIRTY) != 0, + updatePageQueue, &queue); } } diff --git a/src/system/kernel/arch/riscv64/RISCV64VMTranslationMap.cpp b/src/system/kernel/arch/riscv64/RISCV64VMTranslationMap.cpp index 6effcad4d7..17d9dfb0da 100644 --- a/src/system/kernel/arch/riscv64/RISCV64VMTranslationMap.cpp +++ b/src/system/kernel/arch/riscv64/RISCV64VMTranslationMap.cpp @@ -393,49 +393,8 @@ RISCV64VMTranslationMap::UnmapPages(VMArea* area, addr_t base, size_t size, InvalidatePage(start); if (area->cache_type != CACHE_TYPE_DEVICE) { - // get the page - vm_page* page = vm_lookup_page(oldPte.ppn); - ASSERT(page != NULL); - - DEBUG_PAGE_ACCESS_START(page); - - // transfer the accessed/dirty flags to the page - page->accessed = oldPte.isAccessed; - page->modified = oldPte.isDirty; - - // remove the mapping object/decrement the wired_count of the - // page - if (area->wiring == B_NO_LOCK) { - vm_page_mapping* mapping = NULL; - vm_page_mappings::Iterator iterator - = page->mappings.GetIterator(); - while ((mapping = iterator.Next()) != NULL) { - if (mapping->area == area) - break; - } - - ASSERT(mapping != NULL); - - area->mappings.Remove(mapping); - page->mappings.Remove(mapping); - queue.Add(mapping); - } else - page->DecrementWiredCount(); - - if (!page->IsMapped()) { - atomic_add(&gMappedPagesCount, -1); - - if (updatePageQueue) { - if (page->Cache()->temporary) - vm_page_set_state(page, PAGE_STATE_INACTIVE); - else if (page->modified) - vm_page_set_state(page, PAGE_STATE_MODIFIED); - else - vm_page_set_state(page, PAGE_STATE_CACHED); - } - } - - DEBUG_PAGE_ACCESS_END(page); + PageUnmapped(area, oldPte.ppn, oldPte.isAccessed, oldPte.isDirty, + updatePageQueue, &queue); } // flush explicitly, since we directly use the lock diff --git a/src/system/kernel/arch/x86/paging/32bit/X86VMTranslationMap32Bit.cpp b/src/system/kernel/arch/x86/paging/32bit/X86VMTranslationMap32Bit.cpp index ec8f6a105a..b429954b41 100644 --- a/src/system/kernel/arch/x86/paging/32bit/X86VMTranslationMap32Bit.cpp +++ b/src/system/kernel/arch/x86/paging/32bit/X86VMTranslationMap32Bit.cpp @@ -435,52 +435,11 @@ X86VMTranslationMap32Bit::UnmapPages(VMArea* area, addr_t base, size_t size, } if (area->cache_type != CACHE_TYPE_DEVICE) { - // get the page - vm_page* page = vm_lookup_page( - (oldEntry & X86_PTE_ADDRESS_MASK) / B_PAGE_SIZE); - ASSERT(page != NULL); - - DEBUG_PAGE_ACCESS_START(page); - - // transfer the accessed/dirty flags to the page - if ((oldEntry & X86_PTE_ACCESSED) != 0) - page->accessed = true; - if ((oldEntry & X86_PTE_DIRTY) != 0) - page->modified = true; - - // remove the mapping object/decrement the wired_count of the - // page - if (area->wiring == B_NO_LOCK) { - vm_page_mapping* mapping = NULL; - vm_page_mappings::Iterator iterator - = page->mappings.GetIterator(); - while ((mapping = iterator.Next()) != NULL) { - if (mapping->area == area) - break; - } - - ASSERT(mapping != NULL); - - area->mappings.Remove(mapping); - page->mappings.Remove(mapping); - queue.Add(mapping); - } else - page->DecrementWiredCount(); - - if (!page->IsMapped()) { - atomic_add(&gMappedPagesCount, -1); - - if (updatePageQueue) { - if (page->Cache()->temporary) - vm_page_set_state(page, PAGE_STATE_INACTIVE); - else if (page->modified) - vm_page_set_state(page, PAGE_STATE_MODIFIED); - else - vm_page_set_state(page, PAGE_STATE_CACHED); - } - } - - DEBUG_PAGE_ACCESS_END(page); + page_num_t page = (oldEntry & X86_PTE_ADDRESS_MASK) / B_PAGE_SIZE; + PageUnmapped(area, page, + (oldEntry & X86_PTE_ACCESSED) != 0, + (oldEntry & X86_PTE_DIRTY) != 0, + updatePageQueue, &queue); } } diff --git a/src/system/kernel/arch/x86/paging/64bit/X86VMTranslationMap64Bit.cpp b/src/system/kernel/arch/x86/paging/64bit/X86VMTranslationMap64Bit.cpp index 83cef2786a..406e5fd4c3 100644 --- a/src/system/kernel/arch/x86/paging/64bit/X86VMTranslationMap64Bit.cpp +++ b/src/system/kernel/arch/x86/paging/64bit/X86VMTranslationMap64Bit.cpp @@ -437,52 +437,11 @@ X86VMTranslationMap64Bit::UnmapPages(VMArea* area, addr_t base, size_t size, } if (area->cache_type != CACHE_TYPE_DEVICE) { - // get the page - vm_page* page = vm_lookup_page( - (oldEntry & X86_64_PTE_ADDRESS_MASK) / B_PAGE_SIZE); - ASSERT(page != NULL); - - DEBUG_PAGE_ACCESS_START(page); - - // transfer the accessed/dirty flags to the page - if ((oldEntry & X86_64_PTE_ACCESSED) != 0) - page->accessed = true; - if ((oldEntry & X86_64_PTE_DIRTY) != 0) - page->modified = true; - - // remove the mapping object/decrement the wired_count of the - // page - if (area->wiring == B_NO_LOCK) { - vm_page_mapping* mapping = NULL; - vm_page_mappings::Iterator iterator - = page->mappings.GetIterator(); - while ((mapping = iterator.Next()) != NULL) { - if (mapping->area == area) - break; - } - - ASSERT(mapping != NULL); - - area->mappings.Remove(mapping); - page->mappings.Remove(mapping); - queue.Add(mapping); - } else - page->DecrementWiredCount(); - - if (!page->IsMapped()) { - atomic_add(&gMappedPagesCount, -1); - - if (updatePageQueue) { - if (page->Cache()->temporary) - vm_page_set_state(page, PAGE_STATE_INACTIVE); - else if (page->modified) - vm_page_set_state(page, PAGE_STATE_MODIFIED); - else - vm_page_set_state(page, PAGE_STATE_CACHED); - } - } - - DEBUG_PAGE_ACCESS_END(page); + page_num_t page = (oldEntry & X86_64_PTE_ADDRESS_MASK) / B_PAGE_SIZE; + PageUnmapped(area, page, + (oldEntry & X86_64_PTE_ACCESSED) != 0, + (oldEntry & X86_64_PTE_DIRTY) != 0, + updatePageQueue, &queue); } } diff --git a/src/system/kernel/arch/x86/paging/pae/X86VMTranslationMapPAE.cpp b/src/system/kernel/arch/x86/paging/pae/X86VMTranslationMapPAE.cpp index 33bd8193b9..42b28daacf 100644 --- a/src/system/kernel/arch/x86/paging/pae/X86VMTranslationMapPAE.cpp +++ b/src/system/kernel/arch/x86/paging/pae/X86VMTranslationMapPAE.cpp @@ -682,52 +682,11 @@ X86VMTranslationMapPAE::UnmapPages(VMArea* area, addr_t base, size_t size, } if (area->cache_type != CACHE_TYPE_DEVICE) { - // get the page - vm_page* page = vm_lookup_page( - (oldEntry & X86_PAE_PTE_ADDRESS_MASK) / B_PAGE_SIZE); - ASSERT(page != NULL); - - DEBUG_PAGE_ACCESS_START(page); - - // transfer the accessed/dirty flags to the page - if ((oldEntry & X86_PAE_PTE_ACCESSED) != 0) - page->accessed = true; - if ((oldEntry & X86_PAE_PTE_DIRTY) != 0) - page->modified = true; - - // remove the mapping object/decrement the wired_count of the - // page - if (area->wiring == B_NO_LOCK) { - vm_page_mapping* mapping = NULL; - vm_page_mappings::Iterator iterator - = page->mappings.GetIterator(); - while ((mapping = iterator.Next()) != NULL) { - if (mapping->area == area) - break; - } - - ASSERT(mapping != NULL); - - area->mappings.Remove(mapping); - page->mappings.Remove(mapping); - queue.Add(mapping); - } else - page->DecrementWiredCount(); - - if (!page->IsMapped()) { - atomic_add(&gMappedPagesCount, -1); - - if (updatePageQueue) { - if (page->Cache()->temporary) - vm_page_set_state(page, PAGE_STATE_INACTIVE); - else if (page->modified) - vm_page_set_state(page, PAGE_STATE_MODIFIED); - else - vm_page_set_state(page, PAGE_STATE_CACHED); - } - } - - DEBUG_PAGE_ACCESS_END(page); + page_num_t page = (oldEntry & X86_PAE_PTE_ADDRESS_MASK) / B_PAGE_SIZE; + PageUnmapped(area, page, + (oldEntry & X86_PAE_PTE_ACCESSED) != 0, + (oldEntry & X86_PAE_PTE_DIRTY) != 0, + updatePageQueue, &queue); } } diff --git a/src/system/kernel/vm/VMTranslationMap.cpp b/src/system/kernel/vm/VMTranslationMap.cpp index d91afecae6..1cd4663a88 100644 --- a/src/system/kernel/vm/VMTranslationMap.cpp +++ b/src/system/kernel/vm/VMTranslationMap.cpp @@ -158,13 +158,18 @@ VMTranslationMap::DebugGetReverseMappingInfo(phys_addr_t physicalAddress, /*! Called by UnmapPage() after performing the architecture specific part. Looks up the page, updates its flags, removes the page-area mapping, and requeues the page, if necessary. + + If \c mappingsQueue is unspecified, then it unlocks the map and frees the + page-area mapping. If \c mappingsQueue is specified, then it adds the removed + mapping to the queue and does NOT unlock the map. */ void VMTranslationMap::PageUnmapped(VMArea* area, page_num_t pageNumber, - bool accessed, bool modified, bool updatePageQueue) + bool accessed, bool modified, bool updatePageQueue, VMAreaMappings* mappingsQueue) { if (area->cache_type == CACHE_TYPE_DEVICE) { - recursive_lock_unlock(&fLock); + if (mappingsQueue == NULL) + recursive_lock_unlock(&fLock); return; } @@ -173,6 +178,12 @@ VMTranslationMap::PageUnmapped(VMArea* area, page_num_t pageNumber, ASSERT_PRINT(page != NULL, "page number: %#" B_PRIxPHYSADDR ", accessed: %d, modified: %d", pageNumber, accessed, modified); + if (mappingsQueue != NULL) { + DEBUG_PAGE_ACCESS_START(page); + } else { + DEBUG_PAGE_ACCESS_CHECK(page); + } + // transfer the accessed/dirty flags to the page page->accessed |= accessed; page->modified |= modified; @@ -195,7 +206,8 @@ VMTranslationMap::PageUnmapped(VMArea* area, page_num_t pageNumber, } else page->DecrementWiredCount(); - recursive_lock_unlock(&fLock); + if (mappingsQueue == NULL) + recursive_lock_unlock(&fLock); if (!page->IsMapped()) { atomic_add(&gMappedPagesCount, -1); @@ -210,11 +222,19 @@ VMTranslationMap::PageUnmapped(VMArea* area, page_num_t pageNumber, } } + if (mappingsQueue != NULL) { + DEBUG_PAGE_ACCESS_END(page); + } + if (mapping != NULL) { - bool isKernelSpace = area->address_space == VMAddressSpace::Kernel(); - vm_free_page_mapping(pageNumber, mapping, - CACHE_DONT_WAIT_FOR_MEMORY - | (isKernelSpace ? CACHE_DONT_LOCK_KERNEL_SPACE : 0)); + if (mappingsQueue == NULL) { + bool isKernelSpace = area->address_space == VMAddressSpace::Kernel(); + vm_free_page_mapping(pageNumber, mapping, + CACHE_DONT_WAIT_FOR_MEMORY + | (isKernelSpace ? CACHE_DONT_LOCK_KERNEL_SPACE : 0)); + } else { + mappingsQueue->Add(mapping); + } } }