mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 17:05:46 +00:00
[NTOS]: MxGetNextPage is not platform-specific, so share it.
[NTOS]: Factor out computations of NP sizes and limits into MiComputeNonPagedPoolVa. [NTOS]: Fix NP size/limit calculations to use the amount of FREE RAM, not the amount of INSTALLED RAM. [NTOS]: Use Windows 2003's algorithm for NP size on machines with more than 512MB of FREE RAM. [NTOS]: Partly handle the case of machines with NP over 128MB. svn path=/trunk/; revision=45556
This commit is contained in:
parent
b7b948cff5
commit
4e061e178b
3 changed files with 152 additions and 158 deletions
|
@ -29,39 +29,133 @@
|
|||
PMEMORY_ALLOCATION_DESCRIPTOR MxFreeDescriptor;
|
||||
MEMORY_ALLOCATION_DESCRIPTOR MxOldFreeDescriptor;
|
||||
|
||||
/* Template PTE and PDE for a kernel page */
|
||||
MMPTE ValidKernelPde = {.u.Hard.Valid = 1, .u.Hard.Write = 1, .u.Hard.Dirty = 1, .u.Hard.Accessed = 1};
|
||||
MMPTE ValidKernelPte = {.u.Hard.Valid = 1, .u.Hard.Write = 1, .u.Hard.Dirty = 1, .u.Hard.Accessed = 1};
|
||||
|
||||
/* Make the code cleaner with some definitions for size multiples */
|
||||
#define _1KB (1024)
|
||||
#define _1MB (1000 * _1KB)
|
||||
|
||||
/* Architecture specific size of a PDE directory, and size of a page table */
|
||||
#define PDE_SIZE (4096 * sizeof(MMPDE))
|
||||
#define PT_SIZE (1024 * sizeof(MMPTE))
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
PFN_NUMBER
|
||||
VOID
|
||||
NTAPI
|
||||
MxGetNextPage(IN PFN_NUMBER PageCount)
|
||||
MiComputeNonPagedPoolVa(IN ULONG FreePages)
|
||||
{
|
||||
PFN_NUMBER Pfn;
|
||||
|
||||
//
|
||||
// Make sure we have enough pages
|
||||
//
|
||||
if (PageCount > MxFreeDescriptor->PageCount)
|
||||
IN PFN_NUMBER PoolPages;
|
||||
|
||||
/* Check if this is a machine with less than 256MB of RAM, and no overide */
|
||||
if ((MmNumberOfPhysicalPages <= MI_MIN_PAGES_FOR_NONPAGED_POOL_TUNING) &&
|
||||
!(MmSizeOfNonPagedPoolInBytes))
|
||||
{
|
||||
//
|
||||
// Crash the system
|
||||
//
|
||||
KeBugCheckEx(INSTALL_MORE_MEMORY,
|
||||
MmNumberOfPhysicalPages,
|
||||
MxFreeDescriptor->PageCount,
|
||||
MxOldFreeDescriptor.PageCount,
|
||||
PageCount);
|
||||
/* Force the non paged pool to be 2MB so we can reduce RAM usage */
|
||||
MmSizeOfNonPagedPoolInBytes = 2 * _1MB;
|
||||
}
|
||||
|
||||
//
|
||||
// Use our lowest usable free pages
|
||||
//
|
||||
Pfn = MxFreeDescriptor->BasePage;
|
||||
MxFreeDescriptor->BasePage += PageCount;
|
||||
MxFreeDescriptor->PageCount -= PageCount;
|
||||
return Pfn;
|
||||
/* Hyperspace ends here */
|
||||
MmHyperSpaceEnd = (PVOID)((ULONG_PTR)MmSystemCacheWorkingSetList - 1);
|
||||
|
||||
/* Check if the user gave a ridicuously large nonpaged pool RAM size */
|
||||
if ((MmSizeOfNonPagedPoolInBytes >> PAGE_SHIFT) > (FreePages * 7 / 8))
|
||||
{
|
||||
/* More than 7/8ths of RAM was dedicated to nonpaged pool, ignore! */
|
||||
MmSizeOfNonPagedPoolInBytes = 0;
|
||||
}
|
||||
|
||||
/* Check if no registry setting was set, or if the setting was too low */
|
||||
if (MmSizeOfNonPagedPoolInBytes < MmMinimumNonPagedPoolSize)
|
||||
{
|
||||
/* Start with the minimum (256 KB) and add 32 KB for each MB above 4 */
|
||||
MmSizeOfNonPagedPoolInBytes = MmMinimumNonPagedPoolSize;
|
||||
MmSizeOfNonPagedPoolInBytes += (FreePages - 1024) / 256 * MmMinAdditionNonPagedPoolPerMb;
|
||||
}
|
||||
|
||||
/* Check if the registy setting or our dynamic calculation was too high */
|
||||
if (MmSizeOfNonPagedPoolInBytes > MI_MAX_INIT_NONPAGED_POOL_SIZE)
|
||||
{
|
||||
/* Set it to the maximum */
|
||||
MmSizeOfNonPagedPoolInBytes = MI_MAX_INIT_NONPAGED_POOL_SIZE;
|
||||
}
|
||||
|
||||
/* Check if a percentage cap was set through the registry */
|
||||
if (MmMaximumNonPagedPoolPercent) UNIMPLEMENTED;
|
||||
|
||||
/* Page-align the nonpaged pool size */
|
||||
MmSizeOfNonPagedPoolInBytes &= ~(PAGE_SIZE - 1);
|
||||
|
||||
/* Now, check if there was a registry size for the maximum size */
|
||||
if (!MmMaximumNonPagedPoolInBytes)
|
||||
{
|
||||
/* Start with the default (1MB) */
|
||||
MmMaximumNonPagedPoolInBytes = MmDefaultMaximumNonPagedPool;
|
||||
|
||||
/* Add space for PFN database */
|
||||
MmMaximumNonPagedPoolInBytes += (ULONG)
|
||||
PAGE_ALIGN((MmHighestPhysicalPage + 1) * sizeof(MMPFN));
|
||||
|
||||
/* Check if the machine has more than 512MB of free RAM */
|
||||
if (FreePages >= 0x1F000)
|
||||
{
|
||||
/* Add 200KB for each MB above 4 */
|
||||
MmMaximumNonPagedPoolInBytes += (FreePages - 1024) / 256 *
|
||||
(MmMaxAdditionNonPagedPoolPerMb / 2);
|
||||
if (MmMaximumNonPagedPoolInBytes < MI_MAX_NONPAGED_POOL_SIZE)
|
||||
{
|
||||
/* Make it at least 128MB since this machine has a lot of RAM */
|
||||
MmMaximumNonPagedPoolInBytes = MI_MAX_NONPAGED_POOL_SIZE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Add 400KB for each MB above 4 */
|
||||
MmMaximumNonPagedPoolInBytes += (FreePages - 1024) / 256 *
|
||||
MmMaxAdditionNonPagedPoolPerMb;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure there's at least 16 pages + the PFN available for expansion */
|
||||
PoolPages = MmSizeOfNonPagedPoolInBytes + (PAGE_SIZE * 16) +
|
||||
((ULONG)PAGE_ALIGN(MmHighestPhysicalPage + 1) * sizeof(MMPFN));
|
||||
if (MmMaximumNonPagedPoolInBytes < PoolPages)
|
||||
{
|
||||
/* The maximum should be at least high enough to cover all the above */
|
||||
MmMaximumNonPagedPoolInBytes = PoolPages;
|
||||
}
|
||||
|
||||
/* Systems with 2GB of kernel address space get double the size */
|
||||
PoolPages = MI_MAX_NONPAGED_POOL_SIZE * 2;
|
||||
|
||||
/* On the other hand, make sure that PFN + nonpaged pool doesn't get too big */
|
||||
if (MmMaximumNonPagedPoolInBytes > PoolPages)
|
||||
{
|
||||
/* Trim it down to the maximum architectural limit (256MB) */
|
||||
MmMaximumNonPagedPoolInBytes = PoolPages;
|
||||
}
|
||||
|
||||
/* Check if this is a system with > 128MB of non paged pool */
|
||||
if (MmMaximumNonPagedPoolInBytes > MI_MAX_NONPAGED_POOL_SIZE)
|
||||
{
|
||||
/* Check if the initial size is less than the extra 128MB boost */
|
||||
if (MmSizeOfNonPagedPoolInBytes < (MmMaximumNonPagedPoolInBytes -
|
||||
MI_MAX_NONPAGED_POOL_SIZE))
|
||||
{
|
||||
/* FIXME: Should check if the initial pool can be expanded */
|
||||
|
||||
/* Assume no expansion possible, check ift he maximum is too large */
|
||||
if (MmMaximumNonPagedPoolInBytes > (MmSizeOfNonPagedPoolInBytes +
|
||||
MI_MAX_NONPAGED_POOL_SIZE))
|
||||
{
|
||||
/* Set it to the initial value plus the boost */
|
||||
MmMaximumNonPagedPoolInBytes = MmSizeOfNonPagedPoolInBytes +
|
||||
MI_MAX_NONPAGED_POOL_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
@ -71,7 +165,7 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
|||
PLIST_ENTRY NextEntry;
|
||||
PMEMORY_ALLOCATION_DESCRIPTOR MdBlock;
|
||||
ULONG FreePages = 0;
|
||||
PFN_NUMBER PageFrameIndex, PoolPages;
|
||||
PFN_NUMBER PageFrameIndex;
|
||||
PMMPTE StartPde, EndPde, PointerPte, LastPte;
|
||||
MMPTE TempPde, TempPte;
|
||||
PVOID NonPagedPoolExpansionVa;
|
||||
|
@ -79,7 +173,7 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
|||
PFN_NUMBER FreePage, FreePageCount, PagesLeft, BasePage, PageCount;
|
||||
|
||||
/* Check for kernel stack size that's too big */
|
||||
if (MmLargeStackSize > (KERNEL_LARGE_STACK_SIZE / 1024))
|
||||
if (MmLargeStackSize > (KERNEL_LARGE_STACK_SIZE / _1KB))
|
||||
{
|
||||
/* Sanitize to default value */
|
||||
MmLargeStackSize = KERNEL_LARGE_STACK_SIZE;
|
||||
|
@ -87,7 +181,7 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
|||
else
|
||||
{
|
||||
/* Take the registry setting, and convert it into bytes */
|
||||
MmLargeStackSize *= 1024;
|
||||
MmLargeStackSize *= _1KB;
|
||||
|
||||
/* Now align it to a page boundary */
|
||||
MmLargeStackSize = PAGE_ROUND_UP(MmLargeStackSize);
|
||||
|
@ -219,138 +313,8 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
|||
//
|
||||
MxOldFreeDescriptor = *MxFreeDescriptor;
|
||||
|
||||
//
|
||||
// Check if this is a machine with less than 256MB of RAM, and no overide
|
||||
//
|
||||
if ((MmNumberOfPhysicalPages <= MI_MIN_PAGES_FOR_NONPAGED_POOL_TUNING) &&
|
||||
!(MmSizeOfNonPagedPoolInBytes))
|
||||
{
|
||||
//
|
||||
// Force the non paged pool to be 2MB so we can reduce RAM usage
|
||||
//
|
||||
MmSizeOfNonPagedPoolInBytes = 2 * 1024 * 1024;
|
||||
}
|
||||
|
||||
//
|
||||
// Hyperspace ends here
|
||||
//
|
||||
MmHyperSpaceEnd = (PVOID)((ULONG_PTR)MmSystemCacheWorkingSetList - 1);
|
||||
|
||||
//
|
||||
// Check if the user gave a ridicuously large nonpaged pool RAM size
|
||||
//
|
||||
if ((MmSizeOfNonPagedPoolInBytes >> PAGE_SHIFT) >
|
||||
(MmNumberOfPhysicalPages * 7 / 8))
|
||||
{
|
||||
//
|
||||
// More than 7/8ths of RAM was dedicated to nonpaged pool, ignore!
|
||||
//
|
||||
MmSizeOfNonPagedPoolInBytes = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Check if no registry setting was set, or if the setting was too low
|
||||
//
|
||||
if (MmSizeOfNonPagedPoolInBytes < MmMinimumNonPagedPoolSize)
|
||||
{
|
||||
//
|
||||
// Start with the minimum (256 KB) and add 32 KB for each MB above 4
|
||||
//
|
||||
MmSizeOfNonPagedPoolInBytes = MmMinimumNonPagedPoolSize;
|
||||
MmSizeOfNonPagedPoolInBytes += (MmNumberOfPhysicalPages - 1024) /
|
||||
256 * MmMinAdditionNonPagedPoolPerMb;
|
||||
}
|
||||
|
||||
//
|
||||
// Check if the registy setting or our dynamic calculation was too high
|
||||
//
|
||||
if (MmSizeOfNonPagedPoolInBytes > MI_MAX_INIT_NONPAGED_POOL_SIZE)
|
||||
{
|
||||
//
|
||||
// Set it to the maximum
|
||||
//
|
||||
MmSizeOfNonPagedPoolInBytes = MI_MAX_INIT_NONPAGED_POOL_SIZE;
|
||||
}
|
||||
|
||||
//
|
||||
// Check if a percentage cap was set through the registry
|
||||
//
|
||||
if (MmMaximumNonPagedPoolPercent)
|
||||
{
|
||||
//
|
||||
// Don't feel like supporting this right now
|
||||
//
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Page-align the nonpaged pool size
|
||||
//
|
||||
MmSizeOfNonPagedPoolInBytes &= ~(PAGE_SIZE - 1);
|
||||
|
||||
//
|
||||
// Now, check if there was a registry size for the maximum size
|
||||
//
|
||||
if (!MmMaximumNonPagedPoolInBytes)
|
||||
{
|
||||
//
|
||||
// Start with the default (1MB)
|
||||
//
|
||||
MmMaximumNonPagedPoolInBytes = MmDefaultMaximumNonPagedPool;
|
||||
|
||||
//
|
||||
// Add space for PFN database
|
||||
//
|
||||
MmMaximumNonPagedPoolInBytes += (ULONG)
|
||||
PAGE_ALIGN((MmHighestPhysicalPage + 1) * sizeof(MMPFN));
|
||||
|
||||
//
|
||||
// Add 400KB for each MB above 4
|
||||
//
|
||||
MmMaximumNonPagedPoolInBytes += (FreePages - 1024) / 256 *
|
||||
MmMaxAdditionNonPagedPoolPerMb;
|
||||
}
|
||||
|
||||
//
|
||||
// Make sure there's at least 16 pages + the PFN available for expansion
|
||||
//
|
||||
PoolPages = MmSizeOfNonPagedPoolInBytes + (PAGE_SIZE * 16) +
|
||||
((ULONG)PAGE_ALIGN(MmHighestPhysicalPage + 1) *
|
||||
sizeof(MMPFN));
|
||||
if (MmMaximumNonPagedPoolInBytes < PoolPages)
|
||||
{
|
||||
//
|
||||
// Set it to the minimum value for the maximum (yuck!)
|
||||
//
|
||||
MmMaximumNonPagedPoolInBytes = PoolPages;
|
||||
}
|
||||
|
||||
//
|
||||
// Systems with 2GB of kernel address space get double the size
|
||||
//
|
||||
PoolPages = MI_MAX_NONPAGED_POOL_SIZE * 2;
|
||||
|
||||
//
|
||||
// Don't let the maximum go too high
|
||||
//
|
||||
if (MmMaximumNonPagedPoolInBytes > PoolPages)
|
||||
{
|
||||
//
|
||||
// Set it to the upper limit
|
||||
//
|
||||
MmMaximumNonPagedPoolInBytes = PoolPages;
|
||||
}
|
||||
|
||||
//
|
||||
// Check if this is a system with > 128MB of non paged pool
|
||||
//
|
||||
if (MmMaximumNonPagedPoolInBytes > MI_MAX_NONPAGED_POOL_SIZE)
|
||||
{
|
||||
//
|
||||
// FIXME: Unsure about additional checks needed
|
||||
//
|
||||
DPRINT1("Untested path\n");
|
||||
}
|
||||
/* Compute non paged pool limits and size */
|
||||
MiComputeNonPagedPoolVa(FreePages);
|
||||
|
||||
//
|
||||
// Get L2 cache information
|
||||
|
|
|
@ -198,6 +198,12 @@ MiInitMachineDependent(
|
|||
IN PLOADER_PARAMETER_BLOCK LoaderBlock
|
||||
);
|
||||
|
||||
PFN_NUMBER
|
||||
NTAPI
|
||||
MxGetNextPage(
|
||||
IN PFN_NUMBER PageCount
|
||||
);
|
||||
|
||||
PPHYSICAL_MEMORY_DESCRIPTOR
|
||||
NTAPI
|
||||
MmInitializeMemoryLimits(
|
||||
|
|
|
@ -259,6 +259,30 @@ MiSyncARM3WithROS(IN PVOID AddressStart,
|
|||
}
|
||||
}
|
||||
|
||||
PFN_NUMBER
|
||||
NTAPI
|
||||
MxGetNextPage(IN PFN_NUMBER PageCount)
|
||||
{
|
||||
PFN_NUMBER Pfn;
|
||||
|
||||
/* Make sure we have enough pages */
|
||||
if (PageCount > MxFreeDescriptor->PageCount)
|
||||
{
|
||||
/* Crash the system */
|
||||
KeBugCheckEx(INSTALL_MORE_MEMORY,
|
||||
MmNumberOfPhysicalPages,
|
||||
MxFreeDescriptor->PageCount,
|
||||
MxOldFreeDescriptor.PageCount,
|
||||
PageCount);
|
||||
}
|
||||
|
||||
/* Use our lowest usable free pages */
|
||||
Pfn = MxFreeDescriptor->BasePage;
|
||||
MxFreeDescriptor->BasePage += PageCount;
|
||||
MxFreeDescriptor->PageCount -= PageCount;
|
||||
return Pfn;
|
||||
}
|
||||
|
||||
PFN_NUMBER
|
||||
NTAPI
|
||||
MiPagesInLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||
|
|
Loading…
Reference in a new issue