mirror of
https://github.com/reactos/reactos.git
synced 2025-04-28 01:11:35 +00:00
[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 svn path=/trunk/; revision=54771
This commit is contained in:
parent
f8e647e8a2
commit
4cf336fa2a
1 changed files with 45 additions and 14 deletions
|
@ -132,17 +132,20 @@ MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page)
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
ULONG
|
||||||
NTAPI
|
NTAPI
|
||||||
MiTrimMemoryConsumer(ULONG Consumer)
|
MiTrimMemoryConsumer(ULONG Consumer, ULONG InitialTarget)
|
||||||
{
|
{
|
||||||
LONG Target = 0;
|
LONG Target = InitialTarget;
|
||||||
ULONG NrFreedPages = 0;
|
ULONG NrFreedPages = 0;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
/* Make sure we can trim this consumer */
|
/* Make sure we can trim this consumer */
|
||||||
if (!MiMemoryConsumers[Consumer].Trim)
|
if (!MiMemoryConsumers[Consumer].Trim)
|
||||||
return;
|
{
|
||||||
|
/* Return the unmodified initial target */
|
||||||
|
return InitialTarget;
|
||||||
|
}
|
||||||
|
|
||||||
if (MiMemoryConsumers[Consumer].PagesUsed > MiMemoryConsumers[Consumer].PagesTarget)
|
if (MiMemoryConsumers[Consumer].PagesUsed > MiMemoryConsumers[Consumer].PagesTarget)
|
||||||
{
|
{
|
||||||
|
@ -157,8 +160,12 @@ MiTrimMemoryConsumer(ULONG Consumer)
|
||||||
|
|
||||||
if (Target)
|
if (Target)
|
||||||
{
|
{
|
||||||
/* Swap at least MiMinimumPagesPerRun */
|
if (!InitialTarget)
|
||||||
|
{
|
||||||
|
/* If there was no initial target,
|
||||||
|
* swap at least MiMinimumPagesPerRun */
|
||||||
Target = max(Target, MiMinimumPagesPerRun);
|
Target = max(Target, MiMinimumPagesPerRun);
|
||||||
|
}
|
||||||
|
|
||||||
/* Now swap the pages out */
|
/* Now swap the pages out */
|
||||||
Status = MiMemoryConsumers[Consumer].Trim(Target, 0, &NrFreedPages);
|
Status = MiMemoryConsumers[Consumer].Trim(Target, 0, &NrFreedPages);
|
||||||
|
@ -169,6 +176,20 @@ MiTrimMemoryConsumer(ULONG Consumer)
|
||||||
{
|
{
|
||||||
KeBugCheck(MEMORY_MANAGEMENT);
|
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 @@ MiBalancerThread(PVOID Unused)
|
||||||
|
|
||||||
if (Status == STATUS_WAIT_0 || Status == STATUS_WAIT_1)
|
if (Status == STATUS_WAIT_0 || Status == STATUS_WAIT_1)
|
||||||
{
|
{
|
||||||
|
ULONG InitialTarget = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
ULONG OldTarget = InitialTarget;
|
||||||
|
|
||||||
|
/* Trim each consumer */
|
||||||
for (i = 0; i < MC_MAXIMUM; i++)
|
for (i = 0; i < MC_MAXIMUM; i++)
|
||||||
{
|
{
|
||||||
MiTrimMemoryConsumer(i);
|
InitialTarget = MiTrimMemoryConsumer(i, InitialTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MmAvailablePages < MiMinimumAvailablePages)
|
/* No pages left to swap! */
|
||||||
|
if (InitialTarget != 0 &&
|
||||||
|
InitialTarget == OldTarget)
|
||||||
{
|
{
|
||||||
/* This is really bad... */
|
/* Game over */
|
||||||
DPRINT1("Balancer failed to resolve low memory condition! Complete memory exhaustion is imminent!\n");
|
KeBugCheck(NO_PAGES_AVAILABLE);
|
||||||
}
|
}
|
||||||
|
} while (InitialTarget != 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue