- PMM_ALLOCATION_REQUEST Request;
- PLIST_ENTRY Entry;
- KIRQL OldIrql;
-
- if (Page == 0)
- {
- DPRINT1("Tried to release page zero.\n");
- KeBugCheck(MEMORY_MANAGEMENT);
- }
-
- if (MmGetReferenceCountPage(Page) == 1)
- {
- if(Consumer == MC_USER) MmRemoveLRUUserPage(Page);
- (void)InterlockedDecrementUL(&MiMemoryConsumers[Consumer].PagesUsed);
- if ((Entry = ExInterlockedRemoveHeadList(&AllocationListHead, &AllocationListLock)) == NULL)
- {
- OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
- MmDereferencePage(Page);
- KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
- }
- else
- {
- Request = CONTAINING_RECORD(Entry, MM_ALLOCATION_REQUEST, ListEntry);
- MiZeroPhysicalPage(Page);
- Request->Page = Page;
- KeSetEvent(&Request->Event, IO_NO_INCREMENT, FALSE);
- }
- }
- else
- {
- OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
- MmDereferencePage(Page);
- KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
- }
-
- return(STATUS_SUCCESS);
+ PMM_ALLOCATION_REQUEST Request;
+ PLIST_ENTRY Entry;
+ KIRQL OldIrql;
+
+ if (Page == 0)
+ {
+ DPRINT1("Tried to release page zero.\n");
+ KeBugCheck(MEMORY_MANAGEMENT);
+ }
+
+ if (MmGetReferenceCountPage(Page) == 1)
+ {
+ if(Consumer == MC_USER) MmRemoveLRUUserPage(Page);
+ (void)InterlockedDecrementUL(&MiMemoryConsumers[Consumer].PagesUsed);
+ if ((Entry = ExInterlockedRemoveHeadList(&AllocationListHead, &AllocationListLock)) == NULL)
+ {
+ OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+ MmDereferencePage(Page);
+ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+ }
+ else
+ {
+ Request = CONTAINING_RECORD(Entry, MM_ALLOCATION_REQUEST, ListEntry);
+ MiZeroPhysicalPage(Page);
+ Request->Page = Page;
+ KeSetEvent(&Request->Event, IO_NO_INCREMENT, FALSE);
+ }
+ }
+ else
+ {
+ OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+ MmDereferencePage(Page);
+ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+ }
+
+ return(STATUS_SUCCESS);
- ULONG PagesUsed;
- PFN_NUMBER Page;
- KIRQL OldIrql;
-
- /*
- * Make sure we don't exceed our individual target.
- */
- PagesUsed = InterlockedIncrementUL(&MiMemoryConsumers[Consumer].PagesUsed);
- if (PagesUsed > MiMemoryConsumers[Consumer].PagesTarget &&
- !MiIsBalancerThread())
- {
- MmRebalanceMemoryConsumers();
- }
-
- /*
- * Allocate always memory for the non paged pool and for the pager thread.
- */
- if ((Consumer == MC_SYSTEM) || MiIsBalancerThread())
- {
- OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
- Page = MmAllocPage(Consumer);
- KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
- if (Page == 0)
- {
- KeBugCheck(NO_PAGES_AVAILABLE);
- }
- if (Consumer == MC_USER) MmInsertLRULastUserPage(Page);
- *AllocatedPage = Page;
- if (MmAvailablePages < MiMinimumAvailablePages)
- MmRebalanceMemoryConsumers();
- return(STATUS_SUCCESS);
- }
-
- /*
- * Make sure we don't exceed global targets.
- */
- if (MmAvailablePages < MiMinimumAvailablePages)
- {
- MM_ALLOCATION_REQUEST Request;
-
- if (!CanWait)
- {
- (void)InterlockedDecrementUL(&MiMemoryConsumers[Consumer].PagesUsed);
- MmRebalanceMemoryConsumers();
- return(STATUS_NO_MEMORY);
- }
-
- /* Insert an allocation request. */
- Request.Page = 0;
- KeInitializeEvent(&Request.Event, NotificationEvent, FALSE);
-
- ExInterlockedInsertTailList(&AllocationListHead, &Request.ListEntry, &AllocationListLock);
- MmRebalanceMemoryConsumers();
-
- KeWaitForSingleObject(&Request.Event,
- 0,
- KernelMode,
- FALSE,
- NULL);
-
- Page = Request.Page;
- if (Page == 0)
- {
- KeBugCheck(NO_PAGES_AVAILABLE);
- }
-
- if(Consumer == MC_USER) MmInsertLRULastUserPage(Page);
- *AllocatedPage = Page;
-
- if (MmAvailablePages < MiMinimumAvailablePages)
- {
- MmRebalanceMemoryConsumers();
- }
-
- return(STATUS_SUCCESS);
- }
-
- /*
- * Actually allocate the page.
- */
- OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
- Page = MmAllocPage(Consumer);
- KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
- if (Page == 0)
- {
- KeBugCheck(NO_PAGES_AVAILABLE);
- }
- if(Consumer == MC_USER) MmInsertLRULastUserPage(Page);
- *AllocatedPage = Page;
-
- if (MmAvailablePages < MiMinimumAvailablePages)
- {
- MmRebalanceMemoryConsumers();
- }
-
- return(STATUS_SUCCESS);
+ ULONG PagesUsed;
+ PFN_NUMBER Page;
+ KIRQL OldIrql;
+
+ /*
+ * Make sure we don't exceed our individual target.
+ */
+ PagesUsed = InterlockedIncrementUL(&MiMemoryConsumers[Consumer].PagesUsed);
+ if (PagesUsed > MiMemoryConsumers[Consumer].PagesTarget &&
+ !MiIsBalancerThread())
+ {
+ MmRebalanceMemoryConsumers();
+ }
+
+ /*
+ * Allocate always memory for the non paged pool and for the pager thread.
+ */
+ if ((Consumer == MC_SYSTEM) || MiIsBalancerThread())
+ {
+ OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+ Page = MmAllocPage(Consumer);
+ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+ if (Page == 0)
+ {
+ KeBugCheck(NO_PAGES_AVAILABLE);
+ }
+ if (Consumer == MC_USER) MmInsertLRULastUserPage(Page);
+ *AllocatedPage = Page;
+ if (MmAvailablePages < MiMinimumAvailablePages)
+ MmRebalanceMemoryConsumers();
+ return(STATUS_SUCCESS);
+ }
+
+ /*
+ * Make sure we don't exceed global targets.
+ */
+ if (MmAvailablePages < MiMinimumAvailablePages)
+ {
+ MM_ALLOCATION_REQUEST Request;
+
+ if (!CanWait)
+ {
+ (void)InterlockedDecrementUL(&MiMemoryConsumers[Consumer].PagesUsed);
+ MmRebalanceMemoryConsumers();
+ return(STATUS_NO_MEMORY);
+ }
+
+ /* Insert an allocation request. */
+ Request.Page = 0;
+ KeInitializeEvent(&Request.Event, NotificationEvent, FALSE);
+
+ ExInterlockedInsertTailList(&AllocationListHead, &Request.ListEntry, &AllocationListLock);
+ MmRebalanceMemoryConsumers();
+
+ KeWaitForSingleObject(&Request.Event,
+ 0,
+ KernelMode,
+ FALSE,
+ NULL);
+
+ Page = Request.Page;
+ if (Page == 0)
+ {
+ KeBugCheck(NO_PAGES_AVAILABLE);
+ }
+
+ if(Consumer == MC_USER) MmInsertLRULastUserPage(Page);
+ *AllocatedPage = Page;
+
+ if (MmAvailablePages < MiMinimumAvailablePages)
+ {
+ MmRebalanceMemoryConsumers();
+ }
+
+ return(STATUS_SUCCESS);
+ }
+
+ /*
+ * Actually allocate the page.
+ */
+ OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+ Page = MmAllocPage(Consumer);
+ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+ if (Page == 0)
+ {
+ KeBugCheck(NO_PAGES_AVAILABLE);
+ }
+ if(Consumer == MC_USER) MmInsertLRULastUserPage(Page);
+ *AllocatedPage = Page;
+
+ if (MmAvailablePages < MiMinimumAvailablePages)
+ {
+ MmRebalanceMemoryConsumers();
+ }
+
+ return(STATUS_SUCCESS);
- do
- {
- 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
- {
- DPRINT1("KeWaitForMultipleObjects failed, status = %x\n", Status);
- KeBugCheck(MEMORY_MANAGEMENT);
- }
- }
+ do
+ {
+ 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
+ {
+ DPRINT1("KeWaitForMultipleObjects failed, status = %x\n", Status);
+ KeBugCheck(MEMORY_MANAGEMENT);
+ }
+ }