[NTOSKRNL]

- Implement MiIncrementAvailablePages and MiDecrementAvailablePages factoring out duplicated code from a number of locations
- Get rid of MiAllocatePfn. Any further comment would result in excessive use of curse words.

svn path=/trunk/; revision=64528
This commit is contained in:
Timo Kreuzer 2014-10-04 21:17:27 +00:00
parent 87daca2bea
commit 1282829615
3 changed files with 96 additions and 176 deletions

View file

@ -1973,13 +1973,6 @@ MiUnlinkPageFromList(
IN PMMPFN Pfn
);
PFN_NUMBER
NTAPI
MiAllocatePfn(
IN PMMPTE PointerPte,
IN ULONG Protection
);
VOID
NTAPI
MiInitializePfn(

View file

@ -65,6 +65,59 @@ CHAR MI_PFN_CURRENT_PROCESS_NAME[16] = "None yet";
/* FUNCTIONS ******************************************************************/
static
VOID
MiIncrementAvailablePages(
VOID)
{
/* Increment available pages */
MmAvailablePages++;
/* Check if we've reached the configured low memory threshold */
if (MmAvailablePages == MmLowMemoryThreshold)
{
/* Clear the event, because now we're ABOVE the threshold */
KeClearEvent(MiLowMemoryEvent);
}
else if (MmAvailablePages == MmHighMemoryThreshold)
{
/* Otherwise check if we reached the high threshold and signal the event */
KeSetEvent(MiHighMemoryEvent, 0, FALSE);
}
}
static
VOID
MiDecrementAvailablePages(
VOID)
{
ASSERT(MmAvailablePages > 0);
/* See if we hit any thresholds */
if (MmAvailablePages == MmHighMemoryThreshold)
{
/* Clear the high memory event */
KeClearEvent(MiHighMemoryEvent);
}
else if (MmAvailablePages == MmLowMemoryThreshold)
{
/* Signal the low memory event */
KeSetEvent(MiLowMemoryEvent, 0, FALSE);
}
/* One less page */
MmAvailablePages--;
if (MmAvailablePages < MmMinimumFreePages)
{
/* FIXME: Should wake up the MPW and working set manager, if we had one */
DPRINT1("Running low on pages: %lu remaining\n", MmAvailablePages);
/* Call RosMm and see if it can release any pages for us */
MmRebalanceMemoryConsumers();
}
}
VOID
NTAPI
MiZeroPhysicalPage(IN PFN_NUMBER PageFrameIndex)
@ -195,28 +248,8 @@ MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry)
Entry->u1.Flink = Entry->u2.Blink = 0;
ASSERT_LIST_INVARIANT(ListHead);
/* See if we hit any thresholds */
if (MmAvailablePages == MmHighMemoryThreshold)
{
/* Clear the high memory event */
KeClearEvent(MiHighMemoryEvent);
}
else if (MmAvailablePages == MmLowMemoryThreshold)
{
/* Signal the low memory event */
KeSetEvent(MiLowMemoryEvent, 0, FALSE);
}
/* One less page */
if (--MmAvailablePages < MmMinimumFreePages)
{
/* FIXME: Should wake up the MPW and working set manager, if we had one */
DPRINT1("Running low on pages: %lu remaining\n", MmAvailablePages);
/* Call RosMm and see if it can release any pages for us */
MmRebalanceMemoryConsumers();
}
/* Decrement number of available pages */
MiDecrementAvailablePages();
#if MI_TRACE_PFNS
ASSERT(MI_PFN_CURRENT_USAGE != MI_USAGE_NOT_SET);
@ -253,31 +286,12 @@ MiUnlinkPageFromList(IN PMMPFN Pfn)
/* Get the exact list */
ListHead = &MmStandbyPageListByPriority[Pfn->u4.Priority];
/* See if we hit any thresholds */
if (MmAvailablePages == MmHighMemoryThreshold)
{
/* Clear the high memory event */
KeClearEvent(MiHighMemoryEvent);
}
else if (MmAvailablePages == MmLowMemoryThreshold)
{
/* Signal the low memory event */
KeSetEvent(MiLowMemoryEvent, 0, FALSE);
}
/* Decrement number of available pages */
MiDecrementAvailablePages();
/* Decrease transition page counter */
ASSERT(Pfn->u3.e1.PrototypePte == 1); /* Only supported ARM3 case */
MmTransitionSharedPages--;
/* One less page */
if (--MmAvailablePages < MmMinimumFreePages)
{
/* FIXME: Should wake up the MPW and working set manager, if we had one */
DPRINT1("Running low on pages: %lu remaining\n", MmAvailablePages);
/* Call RosMm and see if it can release any pages for us */
MmRebalanceMemoryConsumers();
}
}
else if (ListHead == &MmModifiedPageListHead)
{
@ -442,28 +456,8 @@ MiRemovePageByColor(IN PFN_NUMBER PageIndex,
/* ReactOS Hack */
Pfn1->OriginalPte.u.Long = 0;
/* See if we hit any thresholds */
if (MmAvailablePages == MmHighMemoryThreshold)
{
/* Clear the high memory event */
KeClearEvent(MiHighMemoryEvent);
}
else if (MmAvailablePages == MmLowMemoryThreshold)
{
/* Signal the low memory event */
KeSetEvent(MiLowMemoryEvent, 0, FALSE);
}
/* One less page */
if (--MmAvailablePages < MmMinimumFreePages)
{
/* FIXME: Should wake up the MPW and working set manager, if we had one */
DPRINT1("Running low on pages: %lu remaining\n", MmAvailablePages);
/* Call RosMm and see if it can release any pages for us */
MmRebalanceMemoryConsumers();
}
/* Decrement number of available pages */
MiDecrementAvailablePages();
#if MI_TRACE_PFNS
//ASSERT(MI_PFN_CURRENT_USAGE != MI_USAGE_NOT_SET);
@ -664,20 +658,8 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
Pfn1->u4.InPageError = 0;
Pfn1->u4.AweAllocation = 0;
/* Increase available pages */
MmAvailablePages++;
/* Check if we've reached the configured low memory threshold */
if (MmAvailablePages == MmLowMemoryThreshold)
{
/* Clear the event, because now we're ABOVE the threshold */
KeClearEvent(MiLowMemoryEvent);
}
else if (MmAvailablePages == MmHighMemoryThreshold)
{
/* Otherwise check if we reached the high threshold and signal the event */
KeSetEvent(MiHighMemoryEvent, 0, FALSE);
}
/* Increment number of available pages */
MiIncrementAvailablePages();
/* Get the page color */
Color = PageFrameIndex & MmSecondaryColorMask;
@ -779,20 +761,8 @@ MiInsertStandbyListAtFront(IN PFN_NUMBER PageFrameIndex)
/* Move the page onto its new location */
Pfn1->u3.e1.PageLocation = StandbyPageList;
/* One more page on the system */
MmAvailablePages++;
/* Check if we've reached the configured low memory threshold */
if (MmAvailablePages == MmLowMemoryThreshold)
{
/* Clear the event, because now we're ABOVE the threshold */
KeClearEvent(MiLowMemoryEvent);
}
else if (MmAvailablePages == MmHighMemoryThreshold)
{
/* Otherwise check if we reached the high threshold and signal the event */
KeSetEvent(MiHighMemoryEvent, 0, FALSE);
}
/* Increment number of available pages */
MiIncrementAvailablePages();
}
VOID
@ -919,20 +889,8 @@ MiInsertPageInList(IN PMMPFNLIST ListHead,
/* For zero/free pages, we also have to handle the colored lists */
if (ListName <= StandbyPageList)
{
/* One more page on the system */
MmAvailablePages++;
/* Check if we've reached the configured low memory threshold */
if (MmAvailablePages == MmLowMemoryThreshold)
{
/* Clear the event, because now we're ABOVE the threshold */
KeClearEvent(MiLowMemoryEvent);
}
else if (MmAvailablePages == MmHighMemoryThreshold)
{
/* Otherwise check if we reached the high threshold and signal the event */
KeSetEvent(MiHighMemoryEvent, 0, FALSE);
}
/* Increment number of available pages */
MiIncrementAvailablePages();
/* Sanity checks */
ASSERT(ListName == ZeroedPageList);
@ -1162,54 +1120,6 @@ MiInitializeAndChargePfn(OUT PPFN_NUMBER PageFrameIndex,
return STATUS_SUCCESS;
}
PFN_NUMBER
NTAPI
MiAllocatePfn(IN PMMPTE PointerPte,
IN ULONG Protection)
{
KIRQL OldIrql;
PFN_NUMBER PageFrameIndex;
MMPTE TempPte;
/* Sanity check that we aren't passed a valid PTE */
ASSERT(PointerPte->u.Hard.Valid == 0);
/* Make an empty software PTE */
MI_MAKE_SOFTWARE_PTE(&TempPte, MM_READWRITE);
/* Lock the PFN database */
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
/* Check if we're running low on pages */
if (MmAvailablePages < 128)
{
DPRINT1("Warning, running low on memory: %lu pages left\n", MmAvailablePages);
//MiEnsureAvailablePageOrWait(NULL, OldIrql);
/* Call RosMm and see if it can release any pages for us */
MmRebalanceMemoryConsumers();
}
/* Grab a page */
ASSERT_LIST_INVARIANT(&MmFreePageListHead);
ASSERT_LIST_INVARIANT(&MmZeroedPageListHead);
PageFrameIndex = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
/* Write the software PTE */
MI_WRITE_INVALID_PTE(PointerPte, TempPte);
PointerPte->u.Soft.Protection |= Protection;
/* Initialize its PFN entry */
MiInitializePfn(PageFrameIndex, PointerPte, TRUE);
/* Release the PFN lock and return the page */
ASSERT_LIST_INVARIANT(&MmFreePageListHead);
ASSERT_LIST_INVARIANT(&MmZeroedPageListHead);
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
return PageFrameIndex;
}
VOID
NTAPI
MiDecrementShareCount(IN PMMPFN Pfn1,

View file

@ -99,6 +99,8 @@ MiLoadImageSection(IN OUT PVOID *SectionPtr,
PMMPTE PointerPte, LastPte;
PVOID DriverBase;
MMPTE TempPte;
KIRQL OldIrql;
PFN_NUMBER PageFrameIndex;
PAGED_CODE();
/* Detect session load */
@ -173,31 +175,46 @@ MiLoadImageSection(IN OUT PVOID *SectionPtr,
*ImageBase = DriverBase;
DPRINT1("Loading: %wZ at %p with %lx pages\n", FileName, DriverBase, PteCount);
/* Lock the PFN database */
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
/* Some debug stuff */
MI_SET_USAGE(MI_USAGE_DRIVER_PAGE);
#if MI_TRACE_PFNS
PWCHAR pos = NULL;
ULONG len = 0;
if (FileName->Buffer)
{
pos = wcsrchr(FileName->Buffer, '\\');
len = wcslen(pos) * sizeof(WCHAR);
if (pos) snprintf(MI_PFN_CURRENT_PROCESS_NAME, min(16, len), "%S", pos);
}
#endif
/* Loop the new driver PTEs */
TempPte = ValidKernelPte;
while (PointerPte < LastPte)
{
/* Allocate a page */
MI_SET_USAGE(MI_USAGE_DRIVER_PAGE);
#if MI_TRACE_PFNS
PWCHAR pos = NULL;
ULONG len = 0;
if (FileName->Buffer)
{
pos = wcsrchr(FileName->Buffer, '\\');
len = wcslen(pos) * sizeof(WCHAR);
if (pos) snprintf(MI_PFN_CURRENT_PROCESS_NAME, min(16, len), "%S", pos);
}
#endif
TempPte.u.Hard.PageFrameNumber = MiAllocatePfn(PointerPte, MM_EXECUTE);
/* Make sure the PTE is not valid for whatever reason */
ASSERT(PointerPte->u.Hard.Valid == 0);
/* Write it */
/* Grab a page */
PageFrameIndex = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
/* Initialize its PFN entry */
MiInitializePfn(PageFrameIndex, PointerPte, TRUE);
/* Write the PTE */
TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
MI_WRITE_VALID_PTE(PointerPte, TempPte);
/* Move on */
PointerPte++;
}
/* Release the PFN lock */
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
/* Copy the image */
RtlCopyMemory(DriverBase, Base, PteCount << PAGE_SHIFT);