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=…
==============================================================================
--- 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
{