Author: cgutman
Date: Wed Dec 28 01:18:35 2011
New Revision: 54771

URL: http://svn.reactos.org/svn/reactos?rev=54771&view=rev
Log:
[NTOSKRNL]
- Tweak the balancer to prevent an excessive buildup of user pages while cache 
is paged out completely each run
- Bugcheck if we've trimmed everything as much as possibly but we are still in 
need of pages

Modified:
    trunk/reactos/ntoskrnl/mm/balance.c

Modified: trunk/reactos/ntoskrnl/mm/balance.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/balance.c?rev=54771&r1=54770&r2=54771&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/mm/balance.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/balance.c [iso-8859-1] Wed Dec 28 01:18:35 2011
@@ -132,17 +132,20 @@
    return(STATUS_SUCCESS);
 }
 
-VOID
-NTAPI
-MiTrimMemoryConsumer(ULONG Consumer)
-{
-    LONG Target = 0;
+ULONG
+NTAPI
+MiTrimMemoryConsumer(ULONG Consumer, ULONG InitialTarget)
+{
+    LONG Target = InitialTarget;
     ULONG NrFreedPages = 0;
     NTSTATUS Status;
 
     /* Make sure we can trim this consumer */
     if (!MiMemoryConsumers[Consumer].Trim)
-        return;
+    {
+        /* Return the unmodified initial target */
+        return InitialTarget;
+    }
 
     if (MiMemoryConsumers[Consumer].PagesUsed > 
MiMemoryConsumers[Consumer].PagesTarget)
     {
@@ -157,8 +160,12 @@
 
     if (Target)
     {
-        /* Swap at least MiMinimumPagesPerRun */
-        Target = max(Target, MiMinimumPagesPerRun);
+        if (!InitialTarget)
+        {
+            /* If there was no initial target,
+             * swap at least MiMinimumPagesPerRun */
+            Target = max(Target, MiMinimumPagesPerRun);
+        }
 
         /* Now swap the pages out */
         Status = MiMemoryConsumers[Consumer].Trim(Target, 0, &NrFreedPages);
@@ -169,6 +176,20 @@
         {
             KeBugCheck(MEMORY_MANAGEMENT);
         }
+
+        /* Update the target */
+        if (NrFreedPages < Target)
+            Target -= NrFreedPages;
+        else
+            Target = 0;
+
+        /* Return the remaining pages needed to meet the target */
+        return Target;
+    }
+    else
+    {
+        /* Initial target is zero and we don't have anything else to add */
+        return 0;
     }
 }
 
@@ -348,16 +369,26 @@
 
       if (Status == STATUS_WAIT_0 || Status == STATUS_WAIT_1)
       {
-          for (i = 0; i < MC_MAXIMUM; i++)
+          ULONG InitialTarget = 0;
+
+          do
           {
-              MiTrimMemoryConsumer(i);
-          }
-
-          if (MmAvailablePages < MiMinimumAvailablePages)
-          {
-              /* This is really bad... */
-              DPRINT1("Balancer failed to resolve low memory condition! 
Complete memory exhaustion is imminent!\n");
-          }
+              ULONG OldTarget = InitialTarget;
+
+              /* Trim each consumer */
+              for (i = 0; i < MC_MAXIMUM; i++)
+              {
+                  InitialTarget = MiTrimMemoryConsumer(i, InitialTarget);
+              }
+
+              /* No pages left to swap! */
+              if (InitialTarget != 0 &&
+                  InitialTarget == OldTarget)
+              {
+                  /* Game over */
+                  KeBugCheck(NO_PAGES_AVAILABLE);
+              }
+          } while (InitialTarget != 0);
       }
       else
       {


Reply via email to