[NTOSKRNL]
[reactos.git] / reactos / ntoskrnl / mm / ARM3 / pfnlist.c
index 0a1d426..f8a4b3a 100644 (file)
@@ -12,7 +12,6 @@
 #define NDEBUG
 #include <debug.h>
 
-#line 15 "ARMĀ³::PFNLIST"
 #define MODULE_INVOLVED_IN_ARM3
 #include "../ARM3/miarm.h"
 
@@ -55,6 +54,10 @@ PMMPFNLIST MmPageLocationList[] =
     NULL,
     NULL
 };
+
+ULONG MI_PFN_CURRENT_USAGE;
+CHAR MI_PFN_CURRENT_PROCESS_NAME[16] = "None yet";
+
 /* FUNCTIONS ******************************************************************/
 
 VOID
@@ -82,14 +85,14 @@ MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry)
     ULONG Color;
     PMMCOLOR_TABLES ColorTable;
     PMMPFN Pfn1;
-    
+
     /* Make sure the PFN lock is held */
     ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
 
     /* Make sure the PFN entry isn't in-use */
     ASSERT(Entry->u3.e1.WriteInProgress == 0);
     ASSERT(Entry->u3.e1.ReadInProgress == 0);
-    
+
     /* Find the list for this entry, make sure it's the free or zero list */
     ListHead = MmPageLocationList[Entry->u3.e1.PageLocation];
     ListName = ListHead->ListName;
@@ -100,28 +103,28 @@ MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry)
     /* Remove one count */
     ASSERT(ListHead->Total != 0);
     ListHead->Total--;
-    
+
     /* Get the forward and back pointers */
     OldFlink = Entry->u1.Flink;
     OldBlink = Entry->u2.Blink;
-    
+
     /* Check if the next entry is the list head */
     if (OldFlink != LIST_HEAD)
     {
         /* It is not, so set the backlink of the actual entry, to our backlink */
-        MiGetPfnEntry(OldFlink)->u2.Blink = OldBlink;
+        MI_PFN_ELEMENT(OldFlink)->u2.Blink = OldBlink;
     }
     else
     {
         /* Set the list head's backlink instead */
         ListHead->Blink = OldBlink;
     }
-    
+
     /* Check if the back entry is the list head */
     if (OldBlink != LIST_HEAD)
     {
         /* It is not, so set the backlink of the actual entry, to our backlink */
-        MiGetPfnEntry(OldBlink)->u1.Flink = OldFlink;
+        MI_PFN_ELEMENT(OldBlink)->u1.Flink = OldFlink;
     }
     else
     {
@@ -145,7 +148,7 @@ MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry)
         if (ColorTable->Flink != LIST_HEAD)
         {
             /* And make the previous link point to the head now */
-            MiGetPfnEntry(ColorTable->Flink)->u4.PteFrame = COLORED_LIST_HEAD;
+            MI_PFN_ELEMENT(ColorTable->Flink)->u4.PteFrame = COLORED_LIST_HEAD;
         }
         else
         {
@@ -159,14 +162,14 @@ MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry)
         ASSERT(Entry->u4.PteFrame != COLORED_LIST_HEAD);
 
         /* Make the back link point to whoever the next page is */
-        Pfn1 = MiGetPfnEntry(Entry->u4.PteFrame);
+        Pfn1 = MI_PFN_ELEMENT(Entry->u4.PteFrame);
         Pfn1->OriginalPte.u.Long = Entry->OriginalPte.u.Long;
 
         /* Check if this page was pointing to the head */
         if (Entry->OriginalPte.u.Long != LIST_HEAD)
         {
             /* Make the back link point to the head */
-            Pfn1 = MiGetPfnEntry(Entry->OriginalPte.u.Long);
+            Pfn1 = MI_PFN_ELEMENT(Entry->OriginalPte.u.Long);
             Pfn1->u4.PteFrame = Entry->u4.PteFrame;
         }
         else
@@ -179,7 +182,7 @@ MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry)
     /* One less colored page */
     ASSERT(ColorTable->Count >= 1);
     ColorTable->Count--;
-    
+
     /* ReactOS Hack */
     Entry->OriginalPte.u.Long = 0;
 
@@ -198,12 +201,20 @@ MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry)
         /* Signal the low memory event */
         KeSetEvent(MiLowMemoryEvent, 0, FALSE);
     }
-    
+
     /* One less page */
     if (--MmAvailablePages < MmMinimumFreePages)
     {
         /* FIXME: Should wake up the MPW and working set manager, if we had one */
     }
+
+#if MI_TRACE_PFNS
+    ASSERT(MI_PFN_CURRENT_USAGE != MI_USAGE_NOT_SET);
+    Entry->PfnUsage = MI_PFN_CURRENT_USAGE;
+    memcpy(Entry->ProcessName, MI_PFN_CURRENT_PROCESS_NAME, 16);
+//    MI_PFN_CURRENT_USAGE = MI_USAGE_NOT_SET;
+//    memcpy(MI_PFN_CURRENT_PROCESS_NAME, "Not Set", 16);
+#endif
 }
 
 PFN_NUMBER
@@ -215,7 +226,7 @@ MiRemovePageByColor(IN PFN_NUMBER PageIndex,
     PMMPFNLIST ListHead;
     MMLISTS ListName;
     PFN_NUMBER OldFlink, OldBlink;
-    ULONG OldColor, OldCache;
+    USHORT OldColor, OldCache;
     PMMCOLOR_TABLES ColorTable;
 
     /* Make sure PFN lock is held */
@@ -223,10 +234,10 @@ MiRemovePageByColor(IN PFN_NUMBER PageIndex,
     ASSERT(Color < MmSecondaryColors);
 
     /* Get the PFN entry */
-    Pfn1 = MiGetPfnEntry(PageIndex);
+    Pfn1 = MI_PFN_ELEMENT(PageIndex);
     ASSERT(Pfn1->u3.e1.RemovalRequested == 0);
     ASSERT(Pfn1->u3.e1.Rom == 0);
-    
+
     /* Capture data for later */
     OldColor = Pfn1->u3.e1.PageColor;
     OldCache = Pfn1->u3.e1.CacheAttribute;
@@ -236,42 +247,42 @@ MiRemovePageByColor(IN PFN_NUMBER PageIndex,
     ASSERT_LIST_INVARIANT(ListHead);
     ListName = ListHead->ListName;
     ASSERT(ListName <= FreePageList);
-    
+
     /* Remove a page */
     ListHead->Total--;
 
     /* Get the forward and back pointers */
     OldFlink = Pfn1->u1.Flink;
     OldBlink = Pfn1->u2.Blink;
-    
+
     /* Check if the next entry is the list head */
     if (OldFlink != LIST_HEAD)
     {
         /* It is not, so set the backlink of the actual entry, to our backlink */
-        MiGetPfnEntry(OldFlink)->u2.Blink = OldBlink;
+        MI_PFN_ELEMENT(OldFlink)->u2.Blink = OldBlink;
     }
     else
     {
         /* Set the list head's backlink instead */
-        ListHead->Blink = OldFlink;
+        ListHead->Blink = OldBlink;
     }
-    
+
     /* Check if the back entry is the list head */
     if (OldBlink != LIST_HEAD)
     {
         /* It is not, so set the backlink of the actual entry, to our backlink */
-        MiGetPfnEntry(OldBlink)->u1.Flink = OldFlink;
+        MI_PFN_ELEMENT(OldBlink)->u1.Flink = OldFlink;
     }
     else
     {
         /* Set the list head's backlink instead */
         ListHead->Flink = OldFlink;
     }
-    
+
     /* We are not on a list anymore */
        ASSERT_LIST_INVARIANT(ListHead);
     Pfn1->u1.Flink = Pfn1->u2.Blink = 0;
-    
+
     /* Zero flags but restore color and cache */
     Pfn1->u3.e2.ShortFlags = 0;
     Pfn1->u3.e1.PageColor = OldColor;
@@ -281,25 +292,25 @@ MiRemovePageByColor(IN PFN_NUMBER PageIndex,
     ASSERT(Color < MmSecondaryColors);
     ColorTable = &MmFreePagesByColor[ListName][Color];
     ASSERT(ColorTable->Count >= 1);
-    
+
     /* Set the forward link to whoever we were pointing to */
     ColorTable->Flink = Pfn1->OriginalPte.u.Long;
-    
+
     /* Get the first page on the color list */
     if (ColorTable->Flink == LIST_HEAD)
     {
         /* This is the beginning of the list, so set the sentinel value */
-        ColorTable->Blink = (PVOID)LIST_HEAD;    
+        ColorTable->Blink = (PVOID)LIST_HEAD;
     }
     else
     {
         /* The list is empty, so we are the first page */
-        MiGetPfnEntry(ColorTable->Flink)->u4.PteFrame = COLORED_LIST_HEAD;
+        MI_PFN_ELEMENT(ColorTable->Flink)->u4.PteFrame = COLORED_LIST_HEAD;
     }
-    
+
     /* One less page */
     ColorTable->Count--;
-    
+
     /* ReactOS Hack */
     Pfn1->OriginalPte.u.Long = 0;
 
@@ -314,13 +325,21 @@ MiRemovePageByColor(IN PFN_NUMBER PageIndex,
         /* Signal the low memory event */
         KeSetEvent(MiLowMemoryEvent, 0, FALSE);
     }
-    
+
     /* One less page */
     if (--MmAvailablePages < MmMinimumFreePages)
     {
         /* FIXME: Should wake up the MPW and working set manager, if we had one */
     }
 
+#if MI_TRACE_PFNS
+    //ASSERT(MI_PFN_CURRENT_USAGE != MI_USAGE_NOT_SET);
+    Pfn1->PfnUsage = MI_PFN_CURRENT_USAGE;
+    memcpy(Pfn1->ProcessName, MI_PFN_CURRENT_PROCESS_NAME, 16);
+    //MI_PFN_CURRENT_USAGE = MI_USAGE_NOT_SET;
+    //memcpy(MI_PFN_CURRENT_PROCESS_NAME, "Not Set", 16);
+#endif
+
     /* Return the page */
     return PageIndex;
 }
@@ -336,18 +355,15 @@ MiRemoveAnyPage(IN ULONG Color)
     ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
     ASSERT(MmAvailablePages != 0);
     ASSERT(Color < MmSecondaryColors);
-#if 0
+
     /* Check the colored free list */
     PageIndex = MmFreePagesByColor[FreePageList][Color].Flink;
-    DPRINT1("Found free page: %lx\n", PageIndex);
     if (PageIndex == LIST_HEAD)
     {
         /* Check the colored zero list */
         PageIndex = MmFreePagesByColor[ZeroedPageList][Color].Flink;
-        DPRINT1("Found zero page: %lx\n", PageIndex);
         if (PageIndex == LIST_HEAD)
         {
-#endif
             /* Check the free list */
             ASSERT_LIST_INVARIANT(&MmFreePageListHead);
             PageIndex = MmFreePageListHead.Flink;
@@ -365,22 +381,21 @@ MiRemoveAnyPage(IN ULONG Color)
                     ASSERT(MmZeroedPageListHead.Total == 0);
                 }
             }
-#if 0
         }
     }
-#endif
+
     /* Remove the page from its list */
     PageIndex = MiRemovePageByColor(PageIndex, Color);
 
     /* Sanity checks */
-    Pfn1 = MiGetPfnEntry(PageIndex);
+    Pfn1 = MI_PFN_ELEMENT(PageIndex);
     ASSERT((Pfn1->u3.e1.PageLocation == FreePageList) ||
            (Pfn1->u3.e1.PageLocation == ZeroedPageList));
     ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
     ASSERT(Pfn1->u2.ShareCount == 0);
     ASSERT_LIST_INVARIANT(&MmFreePageListHead);
     ASSERT_LIST_INVARIANT(&MmZeroedPageListHead);
-        
+
     /* Return the page */
     return PageIndex;
 }
@@ -391,7 +406,7 @@ MiRemoveZeroPage(IN ULONG Color)
 {
     PFN_NUMBER PageIndex;
     PMMPFN Pfn1;
-    BOOLEAN Zero;
+    BOOLEAN Zero = FALSE;
 
     /* Make sure PFN lock is held and we have pages */
     ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
@@ -399,26 +414,22 @@ MiRemoveZeroPage(IN ULONG Color)
     ASSERT(Color < MmSecondaryColors);
 
     /* Check the colored zero list */
-#if 0
     PageIndex = MmFreePagesByColor[ZeroedPageList][Color].Flink;
     if (PageIndex == LIST_HEAD)
     {
-#endif
         /* Check the zero list */
         ASSERT_LIST_INVARIANT(&MmZeroedPageListHead);
         PageIndex = MmZeroedPageListHead.Flink;
-        Color = PageIndex & MmSecondaryColorMask;
         if (PageIndex == LIST_HEAD)
         {
             /* This means there's no zero pages, we have to look for free ones */
             ASSERT(MmZeroedPageListHead.Total == 0);
             Zero = TRUE;
-#if 0
+
             /* Check the colored free list */
             PageIndex = MmFreePagesByColor[FreePageList][Color].Flink;
             if (PageIndex == LIST_HEAD)
             {
-#endif
                 /* Check the free list */
                 ASSERT_LIST_INVARIANT(&MmFreePageListHead);
                 PageIndex = MmFreePageListHead.Flink;
@@ -429,26 +440,26 @@ MiRemoveZeroPage(IN ULONG Color)
                     /* FIXME: Should check the standby list */
                     ASSERT(MmZeroedPageListHead.Total == 0);
                 }
-#if 0
             }
-#endif
         }
-#if 0
+        else
+        {
+            Color = PageIndex & MmSecondaryColorMask;
+        }
     }
-#endif
 
     /* Sanity checks */
-    Pfn1 = MiGetPfnEntry(PageIndex);
+    Pfn1 = MI_PFN_ELEMENT(PageIndex);
     ASSERT((Pfn1->u3.e1.PageLocation == FreePageList) ||
            (Pfn1->u3.e1.PageLocation == ZeroedPageList));
 
     /* Remove the page from its list */
     PageIndex = MiRemovePageByColor(PageIndex, Color);
-    ASSERT(Pfn1 == MiGetPfnEntry(PageIndex));
-    
+    ASSERT(Pfn1 == MI_PFN_ELEMENT(PageIndex));
+
     /* Zero it, if needed */
     if (Zero) MiZeroPhysicalPage(PageIndex);
-    
+
     /* Sanity checks */
     ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
     ASSERT(Pfn1->u2.ShareCount == 0);
@@ -477,7 +488,7 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
            (PageFrameIndex >= MmLowestPhysicalPage));
 
     /* Get the PFN entry */
-    Pfn1 = MiGetPfnEntry(PageFrameIndex);
+    Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
 
     /* Sanity checks that a right kind of page is being inserted here */
     ASSERT(Pfn1->u4.MustBeCached == 0);
@@ -496,7 +507,7 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
     if (LastPage != LIST_HEAD)
     {
         /* Link us with the previous page, so we're at the end now */
-        MiGetPfnEntry(LastPage)->u1.Flink = PageFrameIndex;
+        MI_PFN_ELEMENT(LastPage)->u1.Flink = PageFrameIndex;
     }
     else
     {
@@ -550,22 +561,18 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
     {
         /* Get the previous page */
         Blink = (PMMPFN)ColorTable->Blink;
-        
-        /* Make it link to us */
-        Pfn1->u4.PteFrame = MiGetPfnEntryIndex(Blink);
-         
-        /* If there is an original pte, it should be an old link, NOT a ReactOS RMAP */
-        ASSERT(Blink->u4.AweAllocation == FALSE);
+
+        /* Make it link to us, and link back to it */
         Blink->OriginalPte.u.Long = PageFrameIndex;
+        Pfn1->u4.PteFrame = MiGetPfnEntryIndex(Blink);
     }
-    
+
     /* Now initialize our own list pointers */
     ColorTable->Blink = Pfn1;
 
-    /* If there is an original pte, it should be an old link, NOT a ReactOS RMAP */
-    ASSERT(Pfn1->u4.AweAllocation == FALSE);
+    /* This page is now the last */
     Pfn1->OriginalPte.u.Long = LIST_HEAD;
-    
+
     /* And increase the count in the colored list */
     ColorTable->Count++;
 
@@ -576,6 +583,11 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
         MmZeroingPageThreadActive = TRUE;
         KeSetEvent(&MmZeroingPageEvent, IO_NO_INCREMENT, FALSE);
     }
+
+#if MI_TRACE_PFNS
+    Pfn1->PfnUsage = MI_USAGE_FREE_PAGE;
+    RtlZeroMemory(Pfn1->ProcessName, 16);
+#endif
 }
 
 /* Note: This function is hardcoded only for the zeroed page list, for now */
@@ -595,14 +607,14 @@ MiInsertPageInList(IN PMMPFNLIST ListHead,
 
     /* Make sure the lock is held */
     ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
-    
+
     /* Make sure the PFN is valid */
     ASSERT((PageFrameIndex) &&
            (PageFrameIndex <= MmHighestPhysicalPage) &&
            (PageFrameIndex >= MmLowestPhysicalPage));
+
     /* Page should be unused */
-    Pfn1 = MiGetPfnEntry(PageFrameIndex);
+    Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
     ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
     ASSERT(Pfn1->u3.e1.Rom != 1);
 
@@ -626,7 +638,7 @@ MiInsertPageInList(IN PMMPFNLIST ListHead,
     if (Flink != LIST_HEAD)
     {
         /* It wasn't, so update the backlink of the previous head page */
-        Pfn2 = MiGetPfnEntry(Flink);
+        Pfn2 = MI_PFN_ELEMENT(Flink);
         Pfn2->u2.Blink = PageFrameIndex;
     }
     else
@@ -640,7 +652,7 @@ MiInsertPageInList(IN PMMPFNLIST ListHead,
 
     /* One more page on the system */
     MmAvailablePages++;
+
     /* Check if we've reached the configured low memory threshold */
     if (MmAvailablePages == MmLowMemoryThreshold)
     {
@@ -666,9 +678,6 @@ MiInsertPageInList(IN PMMPFNLIST ListHead,
     /* Get the old head */
     Flink = ColorHead->Flink;
 
-    /* If there is an original pte, it should be an old link, NOT a ReactOS RMAP */
-    ASSERT(Pfn1->u4.AweAllocation == FALSE);
-    
     /* Make this page point back to the list, and point forwards to the old head */
     Pfn1->OriginalPte.u.Long = Flink;
     Pfn1->u4.PteFrame = COLORED_LIST_HEAD;
@@ -680,7 +689,7 @@ MiInsertPageInList(IN PMMPFNLIST ListHead,
     if (Flink != LIST_HEAD)
     {
         /* No, so make the old head point to this page */
-        Pfn2 = MiGetPfnEntry(Flink);
+        Pfn2 = MI_PFN_ELEMENT(Flink);
         Pfn2->u4.PteFrame = PageFrameIndex;
     }
     else
@@ -691,6 +700,13 @@ MiInsertPageInList(IN PMMPFNLIST ListHead,
 
     /* One more paged on the colored list */
     ColorHead->Count++;
+
+#if MI_TRACE_PFNS
+    //ASSERT(MI_PFN_CURRENT_USAGE == MI_USAGE_NOT_SET);
+    Pfn1->PfnUsage = MI_USAGE_FREE_PAGE;
+    MI_PFN_CURRENT_USAGE = MI_USAGE_NOT_SET;
+    RtlZeroMemory(Pfn1->ProcessName, 16);
+#endif
 }
 
 VOID
@@ -705,7 +721,7 @@ MiInitializePfn(IN PFN_NUMBER PageFrameIndex,
     ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
 
     /* Setup the PTE */
-    Pfn1 = MiGetPfnEntry(PageFrameIndex);
+    Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
     Pfn1->PteAddress = PointerPte;
 
     /* Check if this PFN is part of a valid address space */
@@ -713,7 +729,7 @@ MiInitializePfn(IN PFN_NUMBER PageFrameIndex,
     {
         /* Only valid from MmCreateProcessAddressSpace path */
         ASSERT(PsGetCurrentProcess()->Vm.WorkingSetSize == 0);
-        
+
         /* Make this a demand zero PTE */
         MI_MAKE_SOFTWARE_PTE(&Pfn1->OriginalPte, MM_READWRITE);
     }
@@ -756,10 +772,68 @@ MiInitializePfn(IN PFN_NUMBER PageFrameIndex,
     Pfn1->u4.PteFrame = PageFrameIndex;
 
     /* Increase its share count so we don't get rid of it */
-    Pfn1 = MiGetPfnEntry(PageFrameIndex);
+    Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
     Pfn1->u2.ShareCount++;
 }
 
+VOID
+NTAPI
+MiInitializePfnAndMakePteValid(IN PFN_NUMBER PageFrameIndex,
+                               IN PMMPTE PointerPte,
+                               IN MMPTE TempPte)
+{
+    PMMPFN Pfn1;
+    NTSTATUS Status;
+    PMMPTE PointerPtePte;
+    ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+
+    /* PTE must be invalid */
+    ASSERT(PointerPte->u.Hard.Valid == 0);
+
+    /* Setup the PTE */
+    Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
+    Pfn1->PteAddress = PointerPte;
+    Pfn1->OriginalPte = DemandZeroPte;
+
+    /* Otherwise this is a fresh page -- set it up */
+    ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
+    Pfn1->u3.e2.ReferenceCount++;
+    Pfn1->u2.ShareCount++;
+    Pfn1->u3.e1.PageLocation = ActiveAndValid;
+    ASSERT(Pfn1->u3.e1.Rom == 0);
+    Pfn1->u3.e1.Modified = 1;
+
+    /* Get the page table for the PTE */
+    PointerPtePte = MiAddressToPte(PointerPte);
+    if (PointerPtePte->u.Hard.Valid == 0)
+    {
+        /* Make sure the PDE gets paged in properly */
+        Status = MiCheckPdeForPagedPool(PointerPte);
+        if (!NT_SUCCESS(Status))
+        {
+            /* Crash */
+            KeBugCheckEx(MEMORY_MANAGEMENT,
+                         0x61940,
+                         (ULONG_PTR)PointerPte,
+                         (ULONG_PTR)PointerPtePte->u.Long,
+                         (ULONG_PTR)MiPteToAddress(PointerPte));
+        }
+    }
+
+    /* Get the PFN for the page table */
+    PageFrameIndex = PFN_FROM_PTE(PointerPtePte);
+    ASSERT(PageFrameIndex != 0);
+    Pfn1->u4.PteFrame = PageFrameIndex;
+
+    /* Increase its share count so we don't get rid of it */
+    Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
+    Pfn1->u2.ShareCount++;
+
+    /* Write valid PTE */
+    MI_WRITE_VALID_PTE(PointerPte, TempPte);
+}
+
+
 PFN_NUMBER
 NTAPI
 MiAllocatePfn(IN PMMPTE PointerPte,
@@ -771,20 +845,26 @@ MiAllocatePfn(IN PMMPTE PointerPte,
 
     /* Sanity check that we aren't passed a valid PTE */
     ASSERT(PointerPte->u.Hard.Valid == 0);
-    
+
     /* Make an empty software PTE */
     MI_MAKE_SOFTWARE_PTE(&TempPte, MM_READWRITE);
     
-    /* Lock the PFN database */
-    OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
-    
     /* Check if we're running low on pages */
     if (MmAvailablePages < 128)
     {
         DPRINT1("Warning, running low on memory: %d pages left\n", MmAvailablePages);
+
         //MiEnsureAvailablePageOrWait(NULL, OldIrql);
+
+        /* Call RosMm and see if it can release any pages for us */
+        MmRebalanceMemoryConsumers();
+
+        DPRINT1("Rebalance complete: %d pages left\n", MmAvailablePages);
     }
-    
+
+    /* Lock the PFN database */
+    OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+
     /* Grab a page */
     ASSERT_LIST_INVARIANT(&MmFreePageListHead);
     ASSERT_LIST_INVARIANT(&MmZeroedPageListHead);
@@ -793,10 +873,10 @@ MiAllocatePfn(IN PMMPTE PointerPte,
     /* Write the software PTE */
     MI_WRITE_INVALID_PTE(PointerPte, TempPte);
     PointerPte->u.Soft.Protection |= Protection;
-    
+
     /* Initialize its PFN entry */
     MiInitializePfn(PageFrameIndex, PointerPte, TRUE);
-    
+
     /* Release the PFN lock and return the page */
     ASSERT_LIST_INVARIANT(&MmFreePageListHead);
     ASSERT_LIST_INVARIANT(&MmZeroedPageListHead);
@@ -810,8 +890,9 @@ MiDecrementShareCount(IN PMMPFN Pfn1,
                       IN PFN_NUMBER PageFrameIndex)
 {
     ASSERT(PageFrameIndex > 0);
-    ASSERT(MiGetPfnEntry(PageFrameIndex) != NULL);
-    ASSERT(Pfn1 == MiGetPfnEntry(PageFrameIndex));
+    ASSERT(MI_PFN_ELEMENT(PageFrameIndex) != NULL);
+    ASSERT(Pfn1 == MI_PFN_ELEMENT(PageFrameIndex));
+    ASSERT(MI_IS_ROS_PFN(Pfn1) == FALSE);
 
     /* Page must be in-use */
     if ((Pfn1->u3.e1.PageLocation != ActiveAndValid) &&
@@ -834,10 +915,10 @@ MiDecrementShareCount(IN PMMPFN Pfn1,
 
         /* Put the page in transition */
         Pfn1->u3.e1.PageLocation = TransitionPage;
-    
+
         /* PFN lock must be held */
         ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
-        
+
         /* Page should at least have one reference */
         ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
         if (Pfn1->u3.e2.ReferenceCount == 1)
@@ -847,13 +928,7 @@ MiDecrementShareCount(IN PMMPFN Pfn1,
 
             /* Clear the last reference */
             Pfn1->u3.e2.ReferenceCount = 0;
-
-            /*
-             * OriginalPte is used by AweReferenceCount in ReactOS, but either 
-             * ways we shouldn't be seeing RMAP entries at this point
-             */
             ASSERT(Pfn1->OriginalPte.u.Soft.Prototype == 0);
-            ASSERT(Pfn1->u4.AweAllocation == FALSE);
 
             /* Mark the page temporarily as valid, we're going to make it free soon */
             Pfn1->u3.e1.PageLocation = ActiveAndValid;
@@ -879,7 +954,7 @@ MiDecrementReferenceCount(IN PMMPFN Pfn1,
 
     /* Sanity checks on the page */
     ASSERT(PageFrameIndex < MmHighestPhysicalPage);
-    ASSERT(Pfn1 == MiGetPfnEntry(PageFrameIndex));
+    ASSERT(Pfn1 == MI_PFN_ELEMENT(PageFrameIndex));
     ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
 
     /* Dereference the page, bail out if it's still alive */
@@ -919,14 +994,14 @@ MiInitializePfnForOtherProcess(IN PFN_NUMBER PageFrameIndex,
                                IN PFN_NUMBER PteFrame)
 {
     PMMPFN Pfn1;
-    
+
     /* Setup the PTE */
-    Pfn1 = MiGetPfnEntry(PageFrameIndex);
+    Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
     Pfn1->PteAddress = PointerPte;
 
     /* Make this a software PTE */
     MI_MAKE_SOFTWARE_PTE(&Pfn1->OriginalPte, MM_READWRITE);
-    
+
     /* Setup the page */
     ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
     Pfn1->u3.e2.ReferenceCount = 1;
@@ -934,15 +1009,15 @@ MiInitializePfnForOtherProcess(IN PFN_NUMBER PageFrameIndex,
     Pfn1->u3.e1.PageLocation = ActiveAndValid;
     Pfn1->u3.e1.Modified = TRUE;
     Pfn1->u4.InPageError = FALSE;
-    
+
     /* Did we get a PFN for the page table */
     if (PteFrame)
     {
         /* Store it */
         Pfn1->u4.PteFrame = PteFrame;
-        
-        /* Increase its share count so we don't get rid of it */    
-        Pfn1 = MiGetPfnEntry(PteFrame);
+
+        /* Increase its share count so we don't get rid of it */
+        Pfn1 = MI_PFN_ELEMENT(PteFrame);
         Pfn1->u2.ShareCount++;
     }
 }