kernel/vm: Free pages via vm_page_free only, not vm_page_set_state.
All consumers of this API should be adjusted here. This partially paves the way for use of committed pages for page tables. Change-Id: Id6fc2edc86fbd80e929c413e23cf8de1509a8215 Reviewed-on: https://review.haiku-os.org/c/haiku/+/8723 Reviewed-by: X512 X512 <[email protected]> Reviewed-by: waddlesplash <[email protected]> Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
bd0f4983c8
commit
b1a913c3aa
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<typename UpdatePte>
|
||||
void ProcessRange(phys_addr_t ptPa, int level, addr_t va, size_t size,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
+3
-3
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user