Author: sir_richard Date: Sat Jun 5 06:16:46 2010 New Revision: 47582
URL: http://svn.reactos.org/svn/reactos?rev=47582&view=rev Log: [NTOS]: Implement MiDeleteSystemPageableVm. [NTOS]: The paged pool free code was behaving incorrectly, assuming that paged pool was "locked down" and never paged out/reused (a valid NT operation mode), while the allocation code was assuming paged pool was a volatile, reusable, pageable resource (normal NT operation mode). The free code now assumes normal operation mode, and actually frees the freed paged pool pages, by using MiDeleteSystemPageableVm. I have a feeling this will make ARM3 paged pool work.
Modified: trunk/reactos/ntoskrnl/mm/ARM3/miarm.h trunk/reactos/ntoskrnl/mm/ARM3/pool.c trunk/reactos/ntoskrnl/mm/ARM3/virtual.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/miarm.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/miarm.h?re... ============================================================================== --- trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] Sat Jun 5 06:16:46 2010 @@ -733,6 +733,15 @@ IN PFN_NUMBER PageFrameIndex );
+PFN_NUMBER +NTAPI +MiDeleteSystemPageableVm( + IN PMMPTE PointerPte, + IN PFN_NUMBER PageCount, + IN ULONG Flags, + OUT PPFN_NUMBER ValidPages +); + PLDR_DATA_TABLE_ENTRY NTAPI MiLookupDataTableEntry(
Modified: trunk/reactos/ntoskrnl/mm/ARM3/pool.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pool.c?rev... ============================================================================== --- trunk/reactos/ntoskrnl/mm/ARM3/pool.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/ARM3/pool.c [iso-8859-1] Sat Jun 5 06:16:46 2010 @@ -264,6 +264,7 @@ // Get the page bit count // i = ((SizeInPages - 1) / 1024) + 1; + DPRINT1("Paged pool expansion: %d %x\n", i, SizeInPages);
// // Check if there is enougn paged pool expansion space left @@ -666,6 +667,11 @@ // NumberOfPages = End - i + 1;
+ /* Delete the actual pages */ + PointerPte = MmPagedPoolInfo.FirstPteForPagedPool + i; + FreePages = MiDeleteSystemPageableVm(PointerPte, NumberOfPages, 0, NULL); + ASSERT(FreePages == NumberOfPages); + // // Acquire the paged pool lock //
Modified: trunk/reactos/ntoskrnl/mm/ARM3/virtual.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/virtual.c?... ============================================================================== --- trunk/reactos/ntoskrnl/mm/ARM3/virtual.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/ARM3/virtual.c [iso-8859-1] Sat Jun 5 06:16:46 2010 @@ -28,6 +28,102 @@ OUT PULONG OldAccessProtection OPTIONAL);
/* PRIVATE FUNCTIONS **********************************************************/ + +PFN_NUMBER +NTAPI +MiDeleteSystemPageableVm(IN PMMPTE PointerPte, + IN PFN_NUMBER PageCount, + IN ULONG Flags, + OUT PPFN_NUMBER ValidPages) +{ + PFN_NUMBER ActualPages = 0; + PETHREAD CurrentThread; + PMMPFN Pfn1, Pfn2; + PFN_NUMBER PageFrameIndex, PageTableIndex; + KIRQL OldIrql, LockIrql; + ASSERT(KeGetCurrentIrql() <= APC_LEVEL); + + /* + * Now we must raise to APC_LEVEL and mark the thread as owner + * We don't actually implement a working set pushlock, so this is only + * for internal consistency (and blocking APCs) + */ + KeRaiseIrql(APC_LEVEL, &LockIrql); + CurrentThread = PsGetCurrentThread(); + KeEnterGuardedRegion(); + ASSERT((CurrentThread->OwnsSystemWorkingSetExclusive == 0) && + (CurrentThread->OwnsSystemWorkingSetShared == 0)); + CurrentThread->OwnsSystemWorkingSetExclusive = 1; + + /* Loop all pages */ + while (PageCount) + { + /* Make sure there's some data about the page */ + if (PointerPte->u.Long) + { + /* As always, only handle current ARM3 scenarios */ + ASSERT(PointerPte->u.Soft.Prototype == 0); + ASSERT(PointerPte->u.Soft.Transition == 0); + ASSERT(PointerPte->u.Hard.Valid == 1); + + /* Normally this is one possibility -- freeing a valid page */ + if (PointerPte->u.Hard.Valid) + { + /* Get the page PFN */ + PageFrameIndex = PFN_FROM_PTE(PointerPte); + Pfn1 = MiGetPfnEntry(PageFrameIndex); + + /* Should not have any working set data yet */ + ASSERT(Pfn1->u1.WsIndex == 0); + + /* Actual valid, legitimate, pages */ + if (ValidPages) *ValidPages++; + + /* Get the page table entry */ + PageTableIndex = Pfn1->u4.PteFrame; + DPRINT1("Page table: %lx\n", PageTableIndex); + Pfn2 = MiGetPfnEntry(PageTableIndex); + + /* Lock the PFN database */ + OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); + + /* Delete it the page */ + MI_SET_PFN_DELETED(Pfn1); + MiDecrementShareCount(Pfn1, PageFrameIndex); + + /* Decrement the page table too */ + #if 0 // ARM3: Dont't trust this yet + MiDecrementShareCount(Pfn2, PageTableIndex); + #endif + + /* Release the PFN database */ + KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); + + /* Destroy the PTE */ + PointerPte->u.Long = 0; + } + + /* Actual legitimate pages */ + ActualPages++; + } + + /* Keep going */ + PointerPte++; + PageCount--; + } + + /* Re-enable APCs */ + ASSERT(KeAreAllApcsDisabled() == TRUE); + CurrentThread->OwnsSystemWorkingSetExclusive = 0; + KeLeaveGuardedRegion(); + KeLowerIrql(LockIrql); + + /* Flush the entire TLB */ + KeFlushEntireTb(TRUE, TRUE); + + /* Done */ + return ActualPages; +}
LONG MiGetExceptionInfo(IN PEXCEPTION_POINTERS ExceptionInfo,