PMMPTE MiSpecialPoolLastPte;
PFN_COUNT MmSpecialPagesInUse;
+PFN_COUNT MmSpecialPagesInUsePeak;
+PFN_COUNT MiSpecialPagesPagable;
+PFN_COUNT MiSpecialPagesPagablePeak;
PFN_COUNT MiSpecialPagesNonPaged;
-PFN_NUMBER MiSpecialPagesNonPagedMaximum;
+PFN_COUNT MiSpecialPagesNonPagedPeak;
+PFN_COUNT MiSpecialPagesNonPagedMaximum;
BOOLEAN MmSpecialPoolCatchOverruns = TRUE;
/* Reserve those PTEs */
do
{
- PointerPte = MiReserveAlignedSystemPtes(SpecialPoolPtes, 0, /*0x400000*/0); // FIXME:
+ PointerPte = MiReserveAlignedSystemPtes(SpecialPoolPtes,
+ SystemPteSpace,
+ /*0x400000*/0); // FIXME:
if (PointerPte) break;
/* Reserving didn't work, so try to reduce the requested size */
LARGE_INTEGER TickCount;
PVOID Entry;
PPOOL_HEADER Header;
+ PFN_COUNT PagesInUse;
DPRINT("MmAllocateSpecialPool(%x %x %x %x)\n", NumberOfBytes, Tag, PoolType, SpecialType);
}
/* TODO: Take into account various limitations */
- /*if ((PoolType != NonPagedPool) &&
- MiSpecialPagesNonPaged > MiSpecialPagesNonPagedMaximum)*/
+
+ /* Heed the maximum limit of nonpaged pages */
+ if ((PoolType == NonPagedPool) &&
+ (MiSpecialPagesNonPaged > MiSpecialPagesNonPagedMaximum))
+ {
+ return NULL;
+ }
/* Lock PFN database */
Irql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
/* Release the PFN database lock */
KeReleaseQueuedSpinLock(LockQueuePfnLock, Irql);
+ /* Increase page counter */
+ PagesInUse = InterlockedIncrementUL(&MmSpecialPagesInUse);
+ if (PagesInUse > MmSpecialPagesInUsePeak)
+ MmSpecialPagesInUsePeak = PagesInUse;
+
/* Put some content into the page. Low value of tick count would do */
Entry = MiPteToAddress(PointerPte);
RtlFillMemory(Entry, PAGE_SIZE, TickCount.LowPart);
/* Also mark the next PTE as special-pool-paged */
PointerPte[1].u.Soft.PageFileHigh |= SPECIAL_POOL_PAGED_PTE;
+
+ /* Increase pagable counter */
+ PagesInUse = InterlockedIncrementUL(&MiSpecialPagesPagable);
+ if (PagesInUse > MiSpecialPagesPagablePeak)
+ MiSpecialPagesPagablePeak = PagesInUse;
}
else
{
/* Mark the next PTE as special-pool-nonpaged */
PointerPte[1].u.Soft.PageFileHigh |= SPECIAL_POOL_NONPAGED_PTE;
+
+ /* Increase nonpaged counter */
+ PagesInUse = InterlockedIncrementUL(&MiSpecialPagesNonPaged);
+ if (PagesInUse > MiSpecialPagesNonPagedPeak)
+ MiSpecialPagesNonPagedPeak = PagesInUse;
}
/* Finally save tag and put allocation time into the header's blocksize.
/* Non pagable. Get PFN element corresponding to the PTE */
Pfn = MI_PFN_ELEMENT(PointerPte->u.Hard.PageFrameNumber);
+ /* Count the page as free */
+ InterlockedDecrementUL(&MiSpecialPagesNonPaged);
+
/* Lock PFN database */
Irql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
/* Pagable. Delete that virtual address */
MiDeleteSystemPageableVm(PointerPte, 1, 0, NULL);
+ /* Count the page as free */
+ InterlockedDecrementUL(&MiSpecialPagesPagable);
+
/* Lock PFN database */
Irql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
}
/* Release the PFN database lock */
KeReleaseQueuedSpinLock(LockQueuePfnLock, Irql);
+
+ /* Update page counter */
+ InterlockedDecrementUL(&MmSpecialPagesInUse);
}
VOID