[NTOSKRNL]
[reactos.git] / reactos / ntoskrnl / mm / balance.c
index cc7b59d..9a65e26 100644 (file)
@@ -23,7 +23,7 @@
 /* TYPES ********************************************************************/
 typedef struct _MM_ALLOCATION_REQUEST
 {
-   PFN_TYPE Page;
+   PFN_NUMBER Page;
    LIST_ENTRY ListEntry;
    KEVENT Event;
 }
@@ -47,14 +47,6 @@ static LONG MiBalancerWork = 0;
 
 /* FUNCTIONS ****************************************************************/
 
-VOID MmPrintMemoryStatistic(VOID)
-{
-   DbgPrint("MC_CACHE %d, MC_USER %d, MC_PPOOL %d, MC_NPPOOL %d, MmAvailablePages %d\n",
-            MiMemoryConsumers[MC_CACHE].PagesUsed, MiMemoryConsumers[MC_USER].PagesUsed,
-            MiMemoryConsumers[MC_PPOOL].PagesUsed, MiMemoryConsumers[MC_NPPOOL].PagesUsed,
-            MmAvailablePages);
-}
-
 VOID
 INIT_FUNCTION
 NTAPI
@@ -70,7 +62,7 @@ MmInitializeBalancer(ULONG NrAvailablePages, ULONG NrSystemPages)
    MiMinimumAvailablePages = 64;
     if ((NrAvailablePages + NrSystemPages) >= 8192)
     {
-        MiMemoryConsumers[MC_CACHE].PagesTarget = NrAvailablePages / 4 * 3;   
+        MiMemoryConsumers[MC_CACHE].PagesTarget = NrAvailablePages / 4 * 3;
     }
     else if ((NrAvailablePages + NrSystemPages) >= 4096)
     {
@@ -78,15 +70,9 @@ MmInitializeBalancer(ULONG NrAvailablePages, ULONG NrSystemPages)
     }
     else
     {
-        MiMemoryConsumers[MC_CACHE].PagesTarget = NrAvailablePages / 8;        
+        MiMemoryConsumers[MC_CACHE].PagesTarget = NrAvailablePages / 8;
     }
-   MiMemoryConsumers[MC_USER].PagesTarget =
-      NrAvailablePages - MiMinimumAvailablePages;
-   MiMemoryConsumers[MC_PPOOL].PagesTarget = NrAvailablePages / 2;
-   MiMemoryConsumers[MC_NPPOOL].PagesTarget = 0xFFFFFFFF;
-   MiMemoryConsumers[MC_NPPOOL].PagesUsed = NrSystemPages;
-   MiMemoryConsumers[MC_SYSTEM].PagesTarget = 0xFFFFFFFF;
-   MiMemoryConsumers[MC_SYSTEM].PagesUsed = 0;
+   MiMemoryConsumers[MC_USER].PagesTarget = NrAvailablePages - MiMinimumAvailablePages;
 }
 
 VOID
@@ -99,9 +85,15 @@ MmInitializeMemoryConsumer(ULONG Consumer,
    MiMemoryConsumers[Consumer].Trim = Trim;
 }
 
+VOID
+NTAPI
+MiZeroPhysicalPage(
+    IN PFN_NUMBER PageFrameIndex
+);
+
 NTSTATUS
 NTAPI
-MmReleasePageMemoryConsumer(ULONG Consumer, PFN_TYPE Page)
+MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page)
 {
    PMM_ALLOCATION_REQUEST Request;
    PLIST_ENTRY Entry;
@@ -131,7 +123,7 @@ MmReleasePageMemoryConsumer(ULONG Consumer, PFN_TYPE Page)
          Request = CONTAINING_RECORD(Entry, MM_ALLOCATION_REQUEST, ListEntry);
          KeReleaseSpinLock(&AllocationListLock, OldIrql);
          if(Consumer == MC_USER) MmRemoveLRUUserPage(Page);
-         MiZeroPage(Page);
+         MiZeroPhysicalPage(Page);
          Request->Page = Page;
          KeSetEvent(&Request->Event, IO_NO_INCREMENT, FALSE);
       }
@@ -139,7 +131,6 @@ MmReleasePageMemoryConsumer(ULONG Consumer, PFN_TYPE Page)
    else
    {
       KeReleaseSpinLock(&AllocationListLock, OldIrql);
-      if(Consumer == MC_USER) MmRemoveLRUUserPage(Page);
       OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
       MmDereferencePage(Page);
       KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
@@ -155,12 +146,9 @@ MiTrimMemoryConsumer(ULONG Consumer)
    LONG Target;
    ULONG NrFreedPages;
 
-   Target = MiMemoryConsumers[Consumer].PagesUsed -
-            MiMemoryConsumers[Consumer].PagesTarget;
-   if (Target < 1)
-   {
-      Target = 1;
-   }
+   Target = max(MiMinimumPagesPerRun,
+                MiMemoryConsumers[Consumer].PagesUsed -
+                MiMemoryConsumers[Consumer].PagesTarget);
 
    if (MiMemoryConsumers[Consumer].Trim != NULL)
    {
@@ -171,17 +159,15 @@ MiTrimMemoryConsumer(ULONG Consumer)
 NTSTATUS
 MmTrimUserMemory(ULONG Target, ULONG Priority, PULONG NrFreedPages)
 {
-    PFN_TYPE CurrentPage;
-    PFN_TYPE NextPage;
+    PFN_NUMBER CurrentPage;
+    PFN_NUMBER NextPage;
     NTSTATUS Status;
-    
+
     (*NrFreedPages) = 0;
-    
+
     CurrentPage = MmGetLRUFirstUserPage();
     while (CurrentPage != 0 && Target > 0)
     {
-        NextPage = MmGetLRUNextUserPage(CurrentPage);
-        
         Status = MmPageOutPhysicalAddress(CurrentPage);
         if (NT_SUCCESS(Status))
         {
@@ -189,10 +175,17 @@ MmTrimUserMemory(ULONG Target, ULONG Priority, PULONG NrFreedPages)
             Target--;
             (*NrFreedPages)++;
         }
-        
+
+        NextPage = MmGetLRUNextUserPage(CurrentPage);
+        if (NextPage <= CurrentPage)
+        {
+            /* We wrapped around, so we're done */
+            break;
+        }
         CurrentPage = NextPage;
     }
-    return(STATUS_SUCCESS);
+
+    return STATUS_SUCCESS;
 }
 
 VOID
@@ -204,7 +197,7 @@ MmRebalanceMemoryConsumers(VOID)
    ULONG NrFreedPages;
    NTSTATUS Status;
 
-   Target = (MiMinimumAvailablePages - MmAvailablePages) + MiPagesRequired;
+   Target = (ULONG)(MiMinimumAvailablePages - MmAvailablePages) + MiPagesRequired;
    Target = max(Target, (LONG) MiMinimumPagesPerRun);
 
    for (i = 0; i < MC_MAXIMUM && Target > 0; i++)
@@ -224,19 +217,17 @@ MmRebalanceMemoryConsumers(VOID)
 static BOOLEAN
 MiIsBalancerThread(VOID)
 {
-   return MiBalancerThreadHandle != NULL &&
-          PsGetCurrentThread() == MiBalancerThreadId.UniqueThread;
+   return (MiBalancerThreadHandle != NULL) &&
+          (PsGetCurrentThreadId() == MiBalancerThreadId.UniqueThread);
 }
 
-VOID NTAPI MiSetConsumer(IN PFN_TYPE Pfn, IN ULONG Consumer);
-
 NTSTATUS
 NTAPI
 MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait,
-                            PPFN_TYPE AllocatedPage)
+                            PPFN_NUMBER AllocatedPage)
 {
    ULONG OldUsed;
-   PFN_TYPE Page;
+   PFN_NUMBER Page;
    KIRQL OldIrql;
 
    /*
@@ -257,7 +248,7 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait,
    /*
     * Allocate always memory for the non paged pool and for the pager thread.
     */
-   if ((Consumer == MC_NPPOOL) || (Consumer == MC_SYSTEM) || MiIsBalancerThread())
+   if ((Consumer == MC_SYSTEM) || MiIsBalancerThread())
    {
       OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
       Page = MmAllocPage(Consumer);
@@ -266,9 +257,11 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait,
       {
          KeBugCheck(NO_PAGES_AVAILABLE);
       }
+      if (Consumer == MC_USER) MmInsertLRULastUserPage(Page);
       *AllocatedPage = Page;
       if (MmAvailablePages <= MiMinimumAvailablePages &&
-            MiBalancerThreadHandle != NULL)
+          MiBalancerThreadHandle != NULL &&
+          !MiIsBalancerThread())
       {
          KeSetEvent(&MiBalancerEvent, IO_NO_INCREMENT, FALSE);
       }
@@ -314,11 +307,18 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait,
       {
          KeBugCheck(NO_PAGES_AVAILABLE);
       }
-      /* Update the Consumer and make the page active */
-      MiSetConsumer(Page, Consumer);
+
       if(Consumer == MC_USER) MmInsertLRULastUserPage(Page);
       *AllocatedPage = Page;
       (void)InterlockedDecrementUL(&MiPagesRequired);
+       
+      if (MmAvailablePages <= MiMinimumAvailablePages &&
+          MiBalancerThreadHandle != NULL &&
+          !MiIsBalancerThread())
+      {
+          KeSetEvent(&MiBalancerEvent, IO_NO_INCREMENT, FALSE);
+      }
+
       return(STATUS_SUCCESS);
    }
 
@@ -334,6 +334,13 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait,
    }
    if(Consumer == MC_USER) MmInsertLRULastUserPage(Page);
    *AllocatedPage = Page;
+    
+   if (MmAvailablePages <= MiMinimumAvailablePages &&
+       MiBalancerThreadHandle != NULL &&
+       !MiIsBalancerThread())
+   {
+       KeSetEvent(&MiBalancerEvent, IO_NO_INCREMENT, FALSE);
+   }
 
    return(STATUS_SUCCESS);
 }