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=5... ============================================================================== --- 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 {