/* TYPES ********************************************************************/
typedef struct _MM_ALLOCATION_REQUEST
{
- PFN_TYPE Page;
+ PFN_NUMBER Page;
LIST_ENTRY ListEntry;
KEVENT Event;
}
/* 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
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)
{
}
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
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;
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);
}
else
{
KeReleaseSpinLock(&AllocationListLock, OldIrql);
- if(Consumer == MC_USER) MmRemoveLRUUserPage(Page);
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
MmDereferencePage(Page);
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
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)
{
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))
{
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
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++)
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;
/*
/*
* 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);
{
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);
}
{
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);
}
}
if(Consumer == MC_USER) MmInsertLRULastUserPage(Page);
*AllocatedPage = Page;
+
+ if (MmAvailablePages <= MiMinimumAvailablePages &&
+ MiBalancerThreadHandle != NULL &&
+ !MiIsBalancerThread())
+ {
+ KeSetEvent(&MiBalancerEvent, IO_NO_INCREMENT, FALSE);
+ }
return(STATUS_SUCCESS);
}