[NTOS/MM]
authorJérôme Gardou <jerome.gardou@reactos.org>
Tue, 18 Oct 2016 20:19:00 +0000 (20:19 +0000)
committerJérôme Gardou <jerome.gardou@reactos.org>
Tue, 18 Oct 2016 20:19:00 +0000 (20:19 +0000)
 - Let the zero page thread decide itself whether it is active or not.
 - Raise the low memory limit for our good old balancer
 - Allow the balancer thread to wait for a page to be freed, with a lower limit than for "regular" page faults
 - Let ARM3 notify RosMm when a page gets freed
CORE-12047 #comment Whole patch got in in r72988, 72989 and 72990

svn path=/trunk/; revision=72990

reactos/ntoskrnl/mm/ARM3/pfnlist.c
reactos/ntoskrnl/mm/ARM3/zeropage.c
reactos/ntoskrnl/mm/balance.c

index 6977f0e..8fc607c 100644 (file)
@@ -64,7 +64,6 @@ ULONG MI_PFN_CURRENT_USAGE;
 CHAR MI_PFN_CURRENT_PROCESS_NAME[16] = "None yet";
 
 /* FUNCTIONS ******************************************************************/
-
 static
 VOID
 MiIncrementAvailablePages(
@@ -597,6 +596,9 @@ MiRemoveZeroPage(IN ULONG Color)
     return PageIndex;
 }
 
+/* HACK for keeping legacy Mm alive */
+extern BOOLEAN MmRosNotifyAvailablePage(PFN_NUMBER PageFrameIndex);
+
 VOID
 NTAPI
 MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
@@ -624,6 +626,13 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
     ASSERT(Pfn1->u4.VerifierAllocation == 0);
     ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
 
+    /* HACK HACK HACK : Feed the page to legacy Mm */
+    if (MmRosNotifyAvailablePage(PageFrameIndex))
+    {
+        DPRINT1("Legacy Mm eating ARM3 page!.\n");
+        return;
+    }
+
     /* Get the free page list and increment its count */
     ListHead = &MmFreePageListHead;
     ASSERT_LIST_INVARIANT(ListHead);
@@ -695,7 +704,6 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
     if ((ListHead->Total >= 8) && !(MmZeroingPageThreadActive))
     {
         /* Set the event */
-        MmZeroingPageThreadActive = TRUE;
         KeSetEvent(&MmZeroingPageEvent, IO_NO_INCREMENT, FALSE);
     }
 
index 1715a93..4b0b9cb 100644 (file)
@@ -68,6 +68,8 @@ MmZeroPageThread(VOID)
                                  NULL,
                                  NULL);
         OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+        MmZeroingPageThreadActive = TRUE;
+
         while (TRUE)
         {
             if (!MmFreePageListHead.Total)
index a82906b..e4b108a 100644 (file)
@@ -59,7 +59,7 @@ MmInitializeBalancer(ULONG NrAvailablePages, ULONG NrSystemPages)
     MiNrTotalPages = NrAvailablePages;
 
     /* Set up targets. */
-    MiMinimumAvailablePages = 128;
+    MiMinimumAvailablePages = 256;
     MiMinimumPagesPerRun = 256;
     if ((NrAvailablePages + NrSystemPages) >= 8192)
     {
@@ -96,9 +96,6 @@ NTSTATUS
 NTAPI
 MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page)
 {
-    PMM_ALLOCATION_REQUEST Request;
-    PLIST_ENTRY Entry;
-
     if (Page == 0)
     {
         DPRINT1("Tried to release page zero.\n");
@@ -109,23 +106,10 @@ MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page)
     {
         if(Consumer == MC_USER) MmRemoveLRUUserPage(Page);
         (void)InterlockedDecrementUL(&MiMemoryConsumers[Consumer].PagesUsed);
-        if ((Entry = ExInterlockedRemoveHeadList(&AllocationListHead, &AllocationListLock)) == NULL)
-        {
-            MmDereferencePage(Page);
-        }
-        else
-        {
-            Request = CONTAINING_RECORD(Entry, MM_ALLOCATION_REQUEST, ListEntry);
-            MiZeroPhysicalPage(Page);
-            Request->Page = Page;
-            KeSetEvent(&Request->Event, IO_NO_INCREMENT, FALSE);
-        }
-    }
-    else
-    {
-        MmDereferencePage(Page);
     }
 
+    MmDereferencePage(Page);
+
     return(STATUS_SUCCESS);
 }
 
@@ -261,7 +245,7 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait,
     /*
      * Allocate always memory for the non paged pool and for the pager thread.
      */
-    if ((Consumer == MC_SYSTEM) || MiIsBalancerThread())
+    if ((Consumer == MC_SYSTEM) /* || MiIsBalancerThread() */)
     {
         Page = MmAllocPage(Consumer);
         if (Page == 0)
@@ -278,7 +262,8 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait,
     /*
      * Make sure we don't exceed global targets.
      */
-    if (MmAvailablePages < MiMinimumAvailablePages)
+    if (((MmAvailablePages < MiMinimumAvailablePages) && !MiIsBalancerThread())
+            || (MmAvailablePages < (MiMinimumAvailablePages / 2)))
     {
         MM_ALLOCATION_REQUEST Request;
 
@@ -418,6 +403,46 @@ MiBalancerThread(PVOID Unused)
     }
 }
 
+BOOLEAN MmRosNotifyAvailablePage(PFN_NUMBER Page)
+{
+    PLIST_ENTRY Entry;
+    PMM_ALLOCATION_REQUEST Request;
+    PMMPFN Pfn1;
+
+    /* Make sure the PFN lock is held */
+    ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+
+    if (!MiMinimumAvailablePages)
+    {
+        /* Dirty way to know if we were initialized. */
+        return FALSE;
+    }
+
+    Entry = ExInterlockedRemoveHeadList(&AllocationListHead, &AllocationListLock);
+    if (!Entry)
+        return FALSE;
+
+    Request = CONTAINING_RECORD(Entry, MM_ALLOCATION_REQUEST, ListEntry);
+    MiZeroPhysicalPage(Page);
+    Request->Page = Page;
+
+    Pfn1 = MiGetPfnEntry(Page);
+    ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
+    Pfn1->u3.e2.ReferenceCount = 1;
+    Pfn1->u3.e1.PageLocation = ActiveAndValid;
+
+    /* This marks the PFN as a ReactOS PFN */
+    Pfn1->u4.AweAllocation = TRUE;
+
+    /* Allocate the extra ReactOS Data and zero it out */
+    Pfn1->u1.SwapEntry = 0;
+    Pfn1->RmapListHead = NULL;
+
+    KeSetEvent(&Request->Event, IO_NO_INCREMENT, FALSE);
+
+    return TRUE;
+}
+
 VOID
 INIT_FUNCTION
 NTAPI