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?r…
==============================================================================
--- 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?re…
==============================================================================
--- 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,