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:
|
protected:
|
||||||
void PageUnmapped(VMArea* area,
|
void PageUnmapped(VMArea* area,
|
||||||
page_num_t pageNumber, bool accessed,
|
page_num_t pageNumber, bool accessed,
|
||||||
bool modified, bool updatePageQueue);
|
bool modified, bool updatePageQueue,
|
||||||
|
VMAreaMappings* mappingsQueue = NULL);
|
||||||
void UnaccessedPageUnmapped(VMArea* area,
|
void UnaccessedPageUnmapped(VMArea* area,
|
||||||
page_num_t pageNumber);
|
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) {
|
if (area->cache_type != CACHE_TYPE_DEVICE) {
|
||||||
// get the page
|
page_num_t page = (oldEntry & ARM_PTE_ADDRESS_MASK) / B_PAGE_SIZE;
|
||||||
vm_page* page = vm_lookup_page(
|
PageUnmapped(area, page,
|
||||||
(oldEntry & ARM_PTE_ADDRESS_MASK) / B_PAGE_SIZE);
|
(oldEntry & ARM_MMU_L2_FLAG_AP0) != 0,
|
||||||
ASSERT(page != NULL);
|
(oldEntry & ARM_MMU_L2_FLAG_AP2) != 0,
|
||||||
|
updatePageQueue, &queue);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -681,49 +681,10 @@ VMSAv8TranslationMap::UnmapPages(VMArea* area, addr_t address, size_t size, bool
|
|||||||
if (area->cache_type == CACHE_TYPE_DEVICE)
|
if (area->cache_type == CACHE_TYPE_DEVICE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// get the page
|
page_num_t page = (oldPte & kPteAddrMask) >> fPageBits;
|
||||||
vm_page* page = vm_lookup_page((oldPte & kPteAddrMask) >> fPageBits);
|
PageUnmapped(area, page,
|
||||||
ASSERT(page != NULL);
|
is_pte_accessed(oldPte), is_pte_dirty(oldPte),
|
||||||
|
updatePageQueue, &queue);
|
||||||
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);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: As in UnmapPage() we can lose page dirty flags here. ATM it's not
|
// 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) {
|
if (area->cache_type != CACHE_TYPE_DEVICE) {
|
||||||
// get the page
|
page_num_t page = (oldEntry & M68K_PTE_ADDRESS_MASK) / B_PAGE_SIZE;
|
||||||
vm_page* page = vm_lookup_page(
|
PageUnmapped(area, page,
|
||||||
(oldEntry & M68K_PTE_ADDRESS_MASK) / B_PAGE_SIZE);
|
(oldEntry & M68K_PTE_ACCESSED) != 0,
|
||||||
ASSERT(page != NULL);
|
(oldEntry & M68K_PTE_DIRTY) != 0,
|
||||||
|
updatePageQueue, &queue);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -798,52 +798,11 @@ PPCVMTranslationMap460::UnmapPages(VMArea* area, addr_t base, size_t size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (area->cache_type != CACHE_TYPE_DEVICE) {
|
if (area->cache_type != CACHE_TYPE_DEVICE) {
|
||||||
// get the page
|
page_num_t page = (oldEntry & PPC_PTE_ADDRESS_MASK) / B_PAGE_SIZE;
|
||||||
vm_page* page = vm_lookup_page(
|
PageUnmapped(area, page,
|
||||||
(oldEntry & PPC_PTE_ADDRESS_MASK) / B_PAGE_SIZE);
|
(oldEntry & PPC_PTE_ACCESSED) != 0,
|
||||||
ASSERT(page != NULL);
|
(oldEntry & PPC_PTE_DIRTY) != 0,
|
||||||
|
updatePageQueue, &queue);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -798,52 +798,11 @@ PPCVMTranslationMapClassic::UnmapPages(VMArea* area, addr_t base, size_t size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (area->cache_type != CACHE_TYPE_DEVICE) {
|
if (area->cache_type != CACHE_TYPE_DEVICE) {
|
||||||
// get the page
|
page_num_t page = (oldEntry & PPC_PTE_ADDRESS_MASK) / B_PAGE_SIZE;
|
||||||
vm_page* page = vm_lookup_page(
|
PageUnmapped(area, page,
|
||||||
(oldEntry & PPC_PTE_ADDRESS_MASK) / B_PAGE_SIZE);
|
(oldEntry & PPC_PTE_ACCESSED) != 0,
|
||||||
ASSERT(page != NULL);
|
(oldEntry & PPC_PTE_DIRTY) != 0,
|
||||||
|
updatePageQueue, &queue);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -393,49 +393,8 @@ RISCV64VMTranslationMap::UnmapPages(VMArea* area, addr_t base, size_t size,
|
|||||||
InvalidatePage(start);
|
InvalidatePage(start);
|
||||||
|
|
||||||
if (area->cache_type != CACHE_TYPE_DEVICE) {
|
if (area->cache_type != CACHE_TYPE_DEVICE) {
|
||||||
// get the page
|
PageUnmapped(area, oldPte.ppn, oldPte.isAccessed, oldPte.isDirty,
|
||||||
vm_page* page = vm_lookup_page(oldPte.ppn);
|
updatePageQueue, &queue);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// flush explicitly, since we directly use the lock
|
// 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) {
|
if (area->cache_type != CACHE_TYPE_DEVICE) {
|
||||||
// get the page
|
page_num_t page = (oldEntry & X86_PTE_ADDRESS_MASK) / B_PAGE_SIZE;
|
||||||
vm_page* page = vm_lookup_page(
|
PageUnmapped(area, page,
|
||||||
(oldEntry & X86_PTE_ADDRESS_MASK) / B_PAGE_SIZE);
|
(oldEntry & X86_PTE_ACCESSED) != 0,
|
||||||
ASSERT(page != NULL);
|
(oldEntry & X86_PTE_DIRTY) != 0,
|
||||||
|
updatePageQueue, &queue);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -437,52 +437,11 @@ X86VMTranslationMap64Bit::UnmapPages(VMArea* area, addr_t base, size_t size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (area->cache_type != CACHE_TYPE_DEVICE) {
|
if (area->cache_type != CACHE_TYPE_DEVICE) {
|
||||||
// get the page
|
page_num_t page = (oldEntry & X86_64_PTE_ADDRESS_MASK) / B_PAGE_SIZE;
|
||||||
vm_page* page = vm_lookup_page(
|
PageUnmapped(area, page,
|
||||||
(oldEntry & X86_64_PTE_ADDRESS_MASK) / B_PAGE_SIZE);
|
(oldEntry & X86_64_PTE_ACCESSED) != 0,
|
||||||
ASSERT(page != NULL);
|
(oldEntry & X86_64_PTE_DIRTY) != 0,
|
||||||
|
updatePageQueue, &queue);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -682,52 +682,11 @@ X86VMTranslationMapPAE::UnmapPages(VMArea* area, addr_t base, size_t size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (area->cache_type != CACHE_TYPE_DEVICE) {
|
if (area->cache_type != CACHE_TYPE_DEVICE) {
|
||||||
// get the page
|
page_num_t page = (oldEntry & X86_PAE_PTE_ADDRESS_MASK) / B_PAGE_SIZE;
|
||||||
vm_page* page = vm_lookup_page(
|
PageUnmapped(area, page,
|
||||||
(oldEntry & X86_PAE_PTE_ADDRESS_MASK) / B_PAGE_SIZE);
|
(oldEntry & X86_PAE_PTE_ACCESSED) != 0,
|
||||||
ASSERT(page != NULL);
|
(oldEntry & X86_PAE_PTE_DIRTY) != 0,
|
||||||
|
updatePageQueue, &queue);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -158,13 +158,18 @@ VMTranslationMap::DebugGetReverseMappingInfo(phys_addr_t physicalAddress,
|
|||||||
/*! Called by UnmapPage() after performing the architecture specific part.
|
/*! Called by UnmapPage() after performing the architecture specific part.
|
||||||
Looks up the page, updates its flags, removes the page-area mapping, and
|
Looks up the page, updates its flags, removes the page-area mapping, and
|
||||||
requeues the page, if necessary.
|
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
|
void
|
||||||
VMTranslationMap::PageUnmapped(VMArea* area, page_num_t pageNumber,
|
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) {
|
if (area->cache_type == CACHE_TYPE_DEVICE) {
|
||||||
recursive_lock_unlock(&fLock);
|
if (mappingsQueue == NULL)
|
||||||
|
recursive_lock_unlock(&fLock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,6 +178,12 @@ VMTranslationMap::PageUnmapped(VMArea* area, page_num_t pageNumber,
|
|||||||
ASSERT_PRINT(page != NULL, "page number: %#" B_PRIxPHYSADDR
|
ASSERT_PRINT(page != NULL, "page number: %#" B_PRIxPHYSADDR
|
||||||
", accessed: %d, modified: %d", pageNumber, accessed, modified);
|
", 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
|
// transfer the accessed/dirty flags to the page
|
||||||
page->accessed |= accessed;
|
page->accessed |= accessed;
|
||||||
page->modified |= modified;
|
page->modified |= modified;
|
||||||
@@ -195,7 +206,8 @@ VMTranslationMap::PageUnmapped(VMArea* area, page_num_t pageNumber,
|
|||||||
} else
|
} else
|
||||||
page->DecrementWiredCount();
|
page->DecrementWiredCount();
|
||||||
|
|
||||||
recursive_lock_unlock(&fLock);
|
if (mappingsQueue == NULL)
|
||||||
|
recursive_lock_unlock(&fLock);
|
||||||
|
|
||||||
if (!page->IsMapped()) {
|
if (!page->IsMapped()) {
|
||||||
atomic_add(&gMappedPagesCount, -1);
|
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) {
|
if (mapping != NULL) {
|
||||||
bool isKernelSpace = area->address_space == VMAddressSpace::Kernel();
|
if (mappingsQueue == NULL) {
|
||||||
vm_free_page_mapping(pageNumber, mapping,
|
bool isKernelSpace = area->address_space == VMAddressSpace::Kernel();
|
||||||
CACHE_DONT_WAIT_FOR_MEMORY
|
vm_free_page_mapping(pageNumber, mapping,
|
||||||
| (isKernelSpace ? CACHE_DONT_LOCK_KERNEL_SPACE : 0));
|
CACHE_DONT_WAIT_FOR_MEMORY
|
||||||
|
| (isKernelSpace ? CACHE_DONT_LOCK_KERNEL_SPACE : 0));
|
||||||
|
} else {
|
||||||
|
mappingsQueue->Add(mapping);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user