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 <[email protected]> Reviewed-by: X512 X512 <[email protected]> Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
6f786da5f7
commit
c5874ee428
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user