[NTOSKRNL]
[reactos.git] / reactos / ntoskrnl / mm / ARM3 / pfnlist.c
index 5e32af3..f8a4b3a 100644 (file)
@@ -226,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 */
@@ -776,6 +776,64 @@ MiInitializePfn(IN PFN_NUMBER 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,
@@ -790,17 +848,23 @@ MiAllocatePfn(IN PMMPTE PointerPte,
 
     /* 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);