diff --git a/src/add-ons/kernel/bus_managers/agp_gart/agp_gart.cpp b/src/add-ons/kernel/bus_managers/agp_gart/agp_gart.cpp index a54e60337f..cf6a2ac9f3 100644 --- a/src/add-ons/kernel/bus_managers/agp_gart/agp_gart.cpp +++ b/src/add-ons/kernel/bus_managers/agp_gart/agp_gart.cpp @@ -718,7 +718,7 @@ Aperture::_Free(aperture_memory *memory) vm_page *page = memory->page; for (uint32 i = 0; i < count; i++, page++) { DEBUG_PAGE_ACCESS_TRANSFER(page, memory->allocating_thread); - vm_page_set_state(page, PAGE_STATE_FREE); + vm_page_free(NULL, page); } memory->page = NULL; @@ -726,7 +726,7 @@ Aperture::_Free(aperture_memory *memory) for (uint32 i = 0; i < count; i++) { DEBUG_PAGE_ACCESS_TRANSFER(memory->pages[i], memory->allocating_thread); - vm_page_set_state(memory->pages[i], PAGE_STATE_FREE); + vm_page_free(NULL, memory->pages[i]); } free(memory->pages); diff --git a/src/add-ons/kernel/drivers/disk/scsi/scsi_cd/scsi_cd.cpp b/src/add-ons/kernel/drivers/disk/scsi/scsi_cd/scsi_cd.cpp index 4985e04a9a..a093250f9e 100644 --- a/src/add-ons/kernel/drivers/disk/scsi/scsi_cd/scsi_cd.cpp +++ b/src/add-ons/kernel/drivers/disk/scsi/scsi_cd/scsi_cd.cpp @@ -180,8 +180,7 @@ test_capacity(cd_driver_info *info) info->scsi->free_ccb(request); for (size_t i = 0; i < numEntries; i++) { - vm_page_set_state(vm_lookup_page(entries[i].address / B_PAGE_SIZE), - PAGE_STATE_FREE); + vm_page_free(NULL, vm_lookup_page(entries[i].address / B_PAGE_SIZE)); } if (info->capacity != info->original_capacity) { diff --git a/src/system/kernel/arch/arm/paging/32bit/ARMVMTranslationMap32Bit.cpp b/src/system/kernel/arch/arm/paging/32bit/ARMVMTranslationMap32Bit.cpp index ca52197ddd..1780a4d3f6 100644 --- a/src/system/kernel/arch/arm/paging/32bit/ARMVMTranslationMap32Bit.cpp +++ b/src/system/kernel/arch/arm/paging/32bit/ARMVMTranslationMap32Bit.cpp @@ -60,6 +60,7 @@ ARMVMTranslationMap32Bit::~ARMVMTranslationMap32Bit() if (fPagingStructures->pgdir_virt != NULL) { // cycle through and free all of the user space pgtables + vm_page_reservation reservation = {}; for (uint32 i = VADDR_TO_PDENT(USER_BASE); i <= VADDR_TO_PDENT(USER_BASE + (USER_SIZE - 1)); i++) { if ((fPagingStructures->pgdir_virt[i] & ARM_PDE_TYPE_MASK) != 0) { @@ -69,9 +70,10 @@ ARMVMTranslationMap32Bit::~ARMVMTranslationMap32Bit() if (!page) panic("destroy_tmap: didn't find pgtable page\n"); DEBUG_PAGE_ACCESS_START(page); - vm_page_set_state(page, PAGE_STATE_FREE); + vm_page_free_etc(NULL, page, &reservation); } } + vm_page_unreserve_pages(&reservation); } fPagingStructures->RemoveReference(); diff --git a/src/system/kernel/arch/arm64/VMSAv8TranslationMap.cpp b/src/system/kernel/arch/arm64/VMSAv8TranslationMap.cpp index 9f5fa63b7b..248408fb87 100644 --- a/src/system/kernel/arch/arm64/VMSAv8TranslationMap.cpp +++ b/src/system/kernel/arch/arm64/VMSAv8TranslationMap.cpp @@ -143,7 +143,9 @@ VMSAv8TranslationMap::~VMSAv8TranslationMap() ThreadCPUPinner pinner(thread_get_current_thread()); InterruptsSpinLocker locker(sAsidLock); - FreeTable(fPageTable, 0, fInitialLevel); + vm_page_reservation reservation = {}; + FreeTable(fPageTable, 0, fInitialLevel, &reservation); + vm_page_unreserve_pages(&reservation); if (fASID != -1) { sAsidMapping[fASID] = NULL; @@ -285,7 +287,8 @@ VMSAv8TranslationMap::TableFromPa(phys_addr_t pa) void -VMSAv8TranslationMap::FreeTable(phys_addr_t ptPa, uint64_t va, int level) +VMSAv8TranslationMap::FreeTable(phys_addr_t ptPa, uint64_t va, int level, + vm_page_reservation* reservation) { ASSERT(level < 4); @@ -302,7 +305,7 @@ VMSAv8TranslationMap::FreeTable(phys_addr_t ptPa, uint64_t va, int level) uint64_t oldPte = (uint64_t) atomic_get_and_set64((int64*) &pt[i], 0); if (level < 3 && (oldPte & kPteTypeMask) == kPteTypeL012Table) { - FreeTable(oldPte & kPteAddrMask, nextVa, level + 1); + FreeTable(oldPte & kPteAddrMask, nextVa, level + 1, reservation); } else if ((oldPte & kPteTypeMask) != 0) { uint64_t fullVa = (fIsKernel ? ~vaMask : 0) | nextVa; @@ -316,7 +319,7 @@ VMSAv8TranslationMap::FreeTable(phys_addr_t ptPa, uint64_t va, int level) vm_page* page = vm_lookup_page(ptPa >> fPageBits); DEBUG_PAGE_ACCESS_START(page); - vm_page_set_state(page, PAGE_STATE_FREE); + vm_page_free_etc(NULL, page, reservation); } @@ -361,7 +364,7 @@ VMSAv8TranslationMap::GetOrMakeTable(phys_addr_t ptPa, int level, int index, // setup and use the one they installed instead. ASSERT((oldPteRefetch & kPteTypeMask) == kPteTypeL012Table); DEBUG_PAGE_ACCESS_START(page); - vm_page_set_state(page, PAGE_STATE_FREE); + vm_page_free_etc(NULL, page, reservation); return oldPteRefetch & kPteAddrMask; } diff --git a/src/system/kernel/arch/arm64/VMSAv8TranslationMap.h b/src/system/kernel/arch/arm64/VMSAv8TranslationMap.h index 851f5fbbca..59fbba72c8 100644 --- a/src/system/kernel/arch/arm64/VMSAv8TranslationMap.h +++ b/src/system/kernel/arch/arm64/VMSAv8TranslationMap.h @@ -115,7 +115,7 @@ private: static uint8_t MairIndex(uint8_t type); bool ValidateVa(addr_t va); uint64_t* TableFromPa(phys_addr_t pa); - void FreeTable(phys_addr_t ptPa, uint64_t va, int level); + void FreeTable(phys_addr_t ptPa, uint64_t va, int level, vm_page_reservation* reservation); phys_addr_t GetOrMakeTable(phys_addr_t ptPa, int level, int index, vm_page_reservation* reservation); template void ProcessRange(phys_addr_t ptPa, int level, addr_t va, size_t size, diff --git a/src/system/kernel/arch/m68k/arch_vm_translation_map_impl.cpp b/src/system/kernel/arch/m68k/arch_vm_translation_map_impl.cpp index 51d3fb7495..4a39b6beda 100644 --- a/src/system/kernel/arch/m68k/arch_vm_translation_map_impl.cpp +++ b/src/system/kernel/arch/m68k/arch_vm_translation_map_impl.cpp @@ -338,6 +338,8 @@ destroy_tmap(vm_translation_map *map) restore_interrupts(state); if (map->arch_data->rtdir_virt != NULL) { + vm_page_reservation reservation = {}; + // cycle through and free all of the user space pgtables // since the size of tables don't match B_PAGE_SIZE, // we alloc several at once, based on modulos, @@ -377,14 +379,15 @@ destroy_tmap(vm_translation_map *map) return; } DEBUG_PAGE_ACCESS_START(page); - vm_page_set_state(page, PAGE_STATE_FREE); + vm_page_free_etc(NULL, page, &reservation); } if (((i + 1) % NUM_DIRTBL_PER_PAGE) == 0) { DEBUG_PAGE_ACCESS_END(dirpage); - vm_page_set_state(dirpage, PAGE_STATE_FREE); + vm_page_free_etc(NULL, dirpage, &reservation); } } free(map->arch_data->rtdir_virt); + vm_page_unreserve_pages(&reservation); } free(map->arch_data); diff --git a/src/system/kernel/arch/m68k/paging/040/M68KVMTranslationMap040.cpp b/src/system/kernel/arch/m68k/paging/040/M68KVMTranslationMap040.cpp index 7d7239285a..6a0b6b5745 100644 --- a/src/system/kernel/arch/m68k/paging/040/M68KVMTranslationMap040.cpp +++ b/src/system/kernel/arch/m68k/paging/040/M68KVMTranslationMap040.cpp @@ -54,6 +54,7 @@ M68KVMTranslationMap040::~M68KVMTranslationMap040() fPageMapper->Delete(); if (fPagingStructures->pgroot_virt != NULL) { + vm_page_reservation reservation = {}; page_root_entry *pgroot_virt = fPagingStructures->pgroot_virt; // cycle through and free all of the user space pgdirs & pgtables @@ -97,14 +98,14 @@ M68KVMTranslationMap040::~M68KVMTranslationMap040() return; } DEBUG_PAGE_ACCESS_START(page); - vm_page_set_state(page, PAGE_STATE_FREE); + vm_page_free_etc(NULL, page, &reservation); } if (((i + 1) % NUM_DIRTBL_PER_PAGE) == 0) { DEBUG_PAGE_ACCESS_END(dirpage); - vm_page_set_state(dirpage, PAGE_STATE_FREE); + vm_page_free_etc(NULL, dirpage, &reservation); } } - + vm_page_unreserve_pages(&reservation); #if 0 @@ -118,7 +119,7 @@ M68KVMTranslationMap040::~M68KVMTranslationMap040() if (!page) panic("destroy_tmap: didn't find pgtable page\n"); DEBUG_PAGE_ACCESS_START(page); - vm_page_set_state(page, PAGE_STATE_FREE); + vm_page_free_etc(NULL, page, &reservation); } } #endif diff --git a/src/system/kernel/arch/ppc/paging/460/PPCVMTranslationMap460.cpp b/src/system/kernel/arch/ppc/paging/460/PPCVMTranslationMap460.cpp index d379e94642..6c4010e7fb 100644 --- a/src/system/kernel/arch/ppc/paging/460/PPCVMTranslationMap460.cpp +++ b/src/system/kernel/arch/ppc/paging/460/PPCVMTranslationMap460.cpp @@ -159,7 +159,7 @@ PPCVMTranslationMap460::~PPCVMTranslationMap460() if (!page) panic("destroy_tmap: didn't find pgtable page\n"); DEBUG_PAGE_ACCESS_START(page); - vm_page_set_state(page, PAGE_STATE_FREE); + vm_page_free_etc(NULL, page, &reservation); } } } diff --git a/src/system/kernel/arch/ppc/paging/classic/PPCVMTranslationMapClassic.cpp b/src/system/kernel/arch/ppc/paging/classic/PPCVMTranslationMapClassic.cpp index e9918c3296..dafd347dfd 100644 --- a/src/system/kernel/arch/ppc/paging/classic/PPCVMTranslationMapClassic.cpp +++ b/src/system/kernel/arch/ppc/paging/classic/PPCVMTranslationMapClassic.cpp @@ -159,7 +159,7 @@ PPCVMTranslationMapClassic::~PPCVMTranslationMapClassic() if (!page) panic("destroy_tmap: didn't find pgtable page\n"); DEBUG_PAGE_ACCESS_START(page); - vm_page_set_state(page, PAGE_STATE_FREE); + vm_page_free_etc(NULL, page, &reservation); } } } diff --git a/src/system/kernel/arch/riscv64/RISCV64VMTranslationMap.cpp b/src/system/kernel/arch/riscv64/RISCV64VMTranslationMap.cpp index 17d9dfb0da..b479353227 100644 --- a/src/system/kernel/arch/riscv64/RISCV64VMTranslationMap.cpp +++ b/src/system/kernel/arch/riscv64/RISCV64VMTranslationMap.cpp @@ -35,7 +35,7 @@ extern uint32 gPlatform; static void -FreePageTable(page_num_t ppn, bool isKernel, uint32 level = 2) +FreePageTable(vm_page_reservation* reservation, page_num_t ppn, bool isKernel, uint32 level = 2) { if (level > 0) { Pte* pte = (Pte*)VirtFromPhys(ppn * B_PAGE_SIZE); @@ -47,12 +47,13 @@ FreePageTable(page_num_t ppn, bool isKernel, uint32 level = 2) } for (uint64 i = beg; i <= end; i++) { if (pte[i].isValid) - FreePageTable(pte[i].ppn, isKernel, level - 1); + FreePageTable(reservation, pte[i].ppn, isKernel, level - 1); } } + vm_page* page = vm_lookup_page(ppn); DEBUG_PAGE_ACCESS_START(page); - vm_page_set_state(page, PAGE_STATE_FREE); + vm_page_free_etc(NULL, page, reservation); } @@ -180,7 +181,9 @@ RISCV64VMTranslationMap::~RISCV64VMTranslationMap() // Can't delete currently used page table ASSERT_ALWAYS(::Satp() != Satp()); - FreePageTable(fPageTable / B_PAGE_SIZE, fIsKernel); + vm_page_reservation reservation = {}; + FreePageTable(&reservation, fPageTable / B_PAGE_SIZE, fIsKernel); + vm_page_unreserve_pages(&reservation); } diff --git a/src/system/kernel/arch/x86/paging/32bit/X86VMTranslationMap32Bit.cpp b/src/system/kernel/arch/x86/paging/32bit/X86VMTranslationMap32Bit.cpp index b429954b41..4bd2760066 100644 --- a/src/system/kernel/arch/x86/paging/32bit/X86VMTranslationMap32Bit.cpp +++ b/src/system/kernel/arch/x86/paging/32bit/X86VMTranslationMap32Bit.cpp @@ -53,6 +53,7 @@ X86VMTranslationMap32Bit::~X86VMTranslationMap32Bit() if (fPageMapper != NULL) fPageMapper->Delete(); + vm_page_reservation reservation = {}; if (fPagingStructures->pgdir_virt != NULL) { // cycle through and free all of the user space pgtables for (uint32 i = VADDR_TO_PDENT(USER_BASE); @@ -64,10 +65,11 @@ X86VMTranslationMap32Bit::~X86VMTranslationMap32Bit() if (!page) panic("destroy_tmap: didn't find pgtable page\n"); DEBUG_PAGE_ACCESS_START(page); - vm_page_set_state(page, PAGE_STATE_FREE); + vm_page_free_etc(NULL, page, &reservation); } } } + vm_page_unreserve_pages(&reservation); fPagingStructures->RemoveReference(); } diff --git a/src/system/kernel/arch/x86/paging/64bit/X86VMTranslationMap64Bit.cpp b/src/system/kernel/arch/x86/paging/64bit/X86VMTranslationMap64Bit.cpp index 406e5fd4c3..e11a5ac797 100644 --- a/src/system/kernel/arch/x86/paging/64bit/X86VMTranslationMap64Bit.cpp +++ b/src/system/kernel/arch/x86/paging/64bit/X86VMTranslationMap64Bit.cpp @@ -52,6 +52,7 @@ X86VMTranslationMap64Bit::~X86VMTranslationMap64Bit() return; if (fPageMapper != NULL) { + vm_page_reservation reservation = {}; phys_addr_t address; vm_page* page; @@ -81,7 +82,7 @@ X86VMTranslationMap64Bit::~X86VMTranslationMap64Bit() } DEBUG_PAGE_ACCESS_START(page); - vm_page_set_state(page, PAGE_STATE_FREE); + vm_page_free_etc(NULL, page, &reservation); } address = virtualPDPT[j] & X86_64_PDPTE_ADDRESS_MASK; @@ -92,7 +93,7 @@ X86VMTranslationMap64Bit::~X86VMTranslationMap64Bit() } DEBUG_PAGE_ACCESS_START(page); - vm_page_set_state(page, PAGE_STATE_FREE); + vm_page_free_etc(NULL, page, &reservation); } address = virtualPML4[i] & X86_64_PML4E_ADDRESS_MASK; @@ -103,9 +104,11 @@ X86VMTranslationMap64Bit::~X86VMTranslationMap64Bit() } DEBUG_PAGE_ACCESS_START(page); - vm_page_set_state(page, PAGE_STATE_FREE); + vm_page_free_etc(NULL, page, &reservation); } + vm_page_unreserve_pages(&reservation); + fPageMapper->Delete(); } diff --git a/src/system/kernel/arch/x86/paging/pae/X86VMTranslationMapPAE.cpp b/src/system/kernel/arch/x86/paging/pae/X86VMTranslationMapPAE.cpp index 42b28daacf..2f6eed1f21 100644 --- a/src/system/kernel/arch/x86/paging/pae/X86VMTranslationMapPAE.cpp +++ b/src/system/kernel/arch/x86/paging/pae/X86VMTranslationMapPAE.cpp @@ -246,6 +246,7 @@ X86VMTranslationMapPAE::~X86VMTranslationMapPAE() STATIC_ASSERT(KERNEL_BASE == 0x80000000 && KERNEL_SIZE == 0x80000000); // assuming 1-1 split of the address space + vm_page_reservation reservation = {}; for (uint32 k = 0; k < 2; k++) { pae_page_directory_entry* pageDir = fPagingStructures->VirtualPageDirs()[k]; @@ -263,10 +264,11 @@ X86VMTranslationMapPAE::~X86VMTranslationMapPAE() address, (k * kPAEPageDirEntryCount + i) * kPAEPageTableRange); DEBUG_PAGE_ACCESS_START(page); - vm_page_set_state(page, PAGE_STATE_FREE); + vm_page_free_etc(NULL, page, &reservation); } } } + vm_page_unreserve_pages(&reservation); fPagingStructures->RemoveReference(); } diff --git a/src/system/kernel/cache/file_cache.cpp b/src/system/kernel/cache/file_cache.cpp index 81fdcb1e29..4531739fc0 100644 --- a/src/system/kernel/cache/file_cache.cpp +++ b/src/system/kernel/cache/file_cache.cpp @@ -223,7 +223,7 @@ PrecacheIO::IOFinished(status_t status, bool partialTransfer, DEBUG_PAGE_ACCESS_TRANSFER(fPages[i], fAllocatingThread); fCache->NotifyPageEvents(fPages[i], PAGE_EVENT_NOT_BUSY); fCache->RemovePage(fPages[i]); - vm_page_set_state(fPages[i], PAGE_STATE_FREE); + vm_page_free(fCache, fPages[i]); } delete this; @@ -319,7 +319,7 @@ reserve_pages(file_cache_ref* ref, vm_page_reservation* reservation, ASSERT(!page->IsMapped()); ASSERT(!page->modified); cache->RemovePage(page); - vm_page_set_state(page, PAGE_STATE_FREE); + vm_page_free(cache, page); left--; } } @@ -421,7 +421,7 @@ read_into_cache(file_cache_ref* ref, void* cookie, off_t offset, for (int32 i = 0; i < pageIndex; i++) { cache->NotifyPageEvents(pages[i], PAGE_EVENT_NOT_BUSY); cache->RemovePage(pages[i]); - vm_page_set_state(pages[i], PAGE_STATE_FREE); + vm_page_free(cache, pages[i]); } return status; diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp index ffd8742724..08052a33c6 100644 --- a/src/system/kernel/vm/vm.cpp +++ b/src/system/kernel/vm/vm.cpp @@ -1955,7 +1955,7 @@ err1: if (page == NULL) panic("couldn't lookup physical page just allocated\n"); - vm_page_set_state(page, PAGE_STATE_FREE); + vm_page_free(NULL, page); } } @@ -3462,24 +3462,28 @@ unmap_and_free_physical_pages(VMTranslationMap* map, addr_t start, addr_t end) { // free all physical pages in the specified range + vm_page_reservation reservation = {}; for (addr_t current = start; current < end; current += B_PAGE_SIZE) { phys_addr_t physicalAddress; uint32 flags; if (map->Query(current, &physicalAddress, &flags) == B_OK - && (flags & PAGE_PRESENT) != 0) { + && (flags & PAGE_PRESENT) != 0) { vm_page* page = vm_lookup_page(physicalAddress / B_PAGE_SIZE); if (page != NULL && page->State() != PAGE_STATE_FREE && page->State() != PAGE_STATE_CLEAR && page->State() != PAGE_STATE_UNUSED) { DEBUG_PAGE_ACCESS_START(page); - vm_page_set_state(page, PAGE_STATE_FREE); + vm_page_free_etc(NULL, page, &reservation); } } } // unmap the memory map->Unmap(start, end); + + // unreserve the memory + vm_page_unreserve_pages(&reservation); } @@ -4306,7 +4310,7 @@ fault_get_page(PageFaultContext& context) cache->NotifyPageEvents(page, PAGE_EVENT_NOT_BUSY); cache->RemovePage(page); - vm_page_set_state(page, PAGE_STATE_FREE); + vm_page_free_etc(cache, page, &context.reservation); cache->ReleaseRefAndUnlock(); return status; diff --git a/src/system/kernel/vm/vm_page.cpp b/src/system/kernel/vm/vm_page.cpp index e6a387fdf8..e103b31d46 100644 --- a/src/system/kernel/vm/vm_page.cpp +++ b/src/system/kernel/vm/vm_page.cpp @@ -4103,7 +4103,7 @@ vm_page_free_etc(VMCache* cache, vm_page* page, PAGE_ASSERT(page, page->State() != PAGE_STATE_FREE && page->State() != PAGE_STATE_CLEAR); - if (page->State() == PAGE_STATE_MODIFIED && cache->temporary) + if (page->State() == PAGE_STATE_MODIFIED && (cache != NULL && cache->temporary)) atomic_add(&sModifiedTemporaryPages, -1); free_page(page, false); @@ -4120,11 +4120,7 @@ vm_page_set_state(vm_page *page, int pageState) PAGE_ASSERT(page, page->State() != PAGE_STATE_FREE && page->State() != PAGE_STATE_CLEAR); - if (pageState == PAGE_STATE_FREE || pageState == PAGE_STATE_CLEAR) { - free_page(page, pageState == PAGE_STATE_CLEAR); - unreserve_pages(1); - } else - set_page_state(page, pageState); + set_page_state(page, pageState); }