mirror of
https://github.com/reactos/reactos.git
synced 2025-01-13 01:22:03 +00:00
Implement paged pool expansion. We are now ready to switch to ARM pool 100%.
svn path=/trunk/; revision=44884
This commit is contained in:
parent
e7c10484b8
commit
b69d9da41a
1 changed files with 127 additions and 5 deletions
|
@ -141,7 +141,7 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType,
|
|||
PMMPTE PointerPte, StartPte;
|
||||
MMPTE TempPte;
|
||||
PMMPFN Pfn1;
|
||||
PVOID BaseVa;
|
||||
PVOID BaseVa, BaseVaStart;
|
||||
PMMFREE_POOL_ENTRY FreeEntry;
|
||||
PKSPIN_LOCK_QUEUE LockQueue;
|
||||
|
||||
|
@ -167,6 +167,17 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType,
|
|||
SizeInPages,
|
||||
MmPagedPoolInfo.PagedPoolHint);
|
||||
if (i == 0xFFFFFFFF)
|
||||
{
|
||||
//
|
||||
// Get the page bit count
|
||||
//
|
||||
i = ((SizeInPages - 1) / 1024) + 1;
|
||||
|
||||
//
|
||||
// Check if there is enougn paged pool expansion space left
|
||||
//
|
||||
if (MmPagedPoolInfo.NextPdeForPagedPoolExpansion >
|
||||
MiAddressToPte(MmPagedPoolInfo.LastPteForPagedPool))
|
||||
{
|
||||
//
|
||||
// Out of memory!
|
||||
|
@ -176,6 +187,117 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Check if we'll have to expand past the last PTE we have available
|
||||
//
|
||||
if (((i - 1) + MmPagedPoolInfo.NextPdeForPagedPoolExpansion) >
|
||||
MiAddressToPte(MmPagedPoolInfo.LastPteForPagedPool))
|
||||
{
|
||||
//
|
||||
// We can only support this much then
|
||||
//
|
||||
SizeInPages = MiAddressToPte(MmPagedPoolInfo.LastPteForPagedPool) -
|
||||
MmPagedPoolInfo.NextPdeForPagedPoolExpansion +
|
||||
1;
|
||||
ASSERT(SizeInPages < i);
|
||||
i = SizeInPages;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Otherwise, there is plenty of space left for this expansion
|
||||
//
|
||||
SizeInPages = i;
|
||||
}
|
||||
|
||||
//
|
||||
// Get the template PTE we'll use to expand
|
||||
//
|
||||
TempPte = HyperTemplatePte;
|
||||
|
||||
//
|
||||
// Get the first PTE in expansion space
|
||||
//
|
||||
PointerPte = MmPagedPoolInfo.NextPdeForPagedPoolExpansion;
|
||||
BaseVa = MiPteToAddress(PointerPte);
|
||||
BaseVaStart = BaseVa;
|
||||
|
||||
//
|
||||
// Lock the PFN database and loop pages
|
||||
//
|
||||
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
|
||||
do
|
||||
{
|
||||
//
|
||||
// It should not already be valid
|
||||
//
|
||||
ASSERT(PointerPte->u.Hard.Valid == 0);
|
||||
|
||||
//
|
||||
// Request a paged pool page and write the PFN for it
|
||||
//
|
||||
PageFrameNumber = MmAllocPage(MC_PPOOL, 0);
|
||||
TempPte.u.Hard.PageFrameNumber = PageFrameNumber;
|
||||
|
||||
//
|
||||
// Save it into our double-buffered system page directory
|
||||
//
|
||||
MmSystemPagePtes[(ULONG_PTR)PointerPte & (PAGE_SIZE - 1) /
|
||||
sizeof(MMPTE)] = TempPte;
|
||||
|
||||
//
|
||||
// Write the actual PTE now
|
||||
//
|
||||
*PointerPte++ = TempPte;
|
||||
|
||||
//
|
||||
// Move on to the next expansion address
|
||||
//
|
||||
BaseVa = (PVOID)((ULONG_PTR)BaseVa + PAGE_SIZE);
|
||||
} while (--i > 0);
|
||||
|
||||
//
|
||||
// Release the PFN database lock
|
||||
//
|
||||
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
|
||||
|
||||
//
|
||||
// These pages are now available, clear their availablity bits
|
||||
//
|
||||
RtlClearBits(MmPagedPoolInfo.PagedPoolAllocationMap,
|
||||
(MmPagedPoolInfo.NextPdeForPagedPoolExpansion -
|
||||
MiAddressToPte(MmPagedPoolInfo.FirstPteForPagedPool)) *
|
||||
1024,
|
||||
SizeInPages * 1024);
|
||||
|
||||
//
|
||||
// Update the next expansion location
|
||||
//
|
||||
MmPagedPoolInfo.NextPdeForPagedPoolExpansion += SizeInPages;
|
||||
|
||||
//
|
||||
// Zero out the newly available memory
|
||||
//
|
||||
RtlZeroMemory(BaseVaStart, SizeInPages * PAGE_SIZE);
|
||||
|
||||
//
|
||||
// Now try consuming the pages again
|
||||
//
|
||||
SizeInPages = BYTES_TO_PAGES(SizeInBytes);
|
||||
i = RtlFindClearBitsAndSet(MmPagedPoolInfo.PagedPoolAllocationMap,
|
||||
SizeInPages,
|
||||
0);
|
||||
if (i == 0xFFFFFFFF)
|
||||
{
|
||||
//
|
||||
// Out of memory!
|
||||
//
|
||||
DPRINT1("OUT OF PAGED POOL!!!\n");
|
||||
KeReleaseGuardedMutex(&MmPagedPoolMutex);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Update the pool hint if the request was just one page
|
||||
//
|
||||
|
|
Loading…
Reference in a new issue