diff options
Diffstat (limited to 'private/ntos/mm/miglobal.c')
-rw-r--r-- | private/ntos/mm/miglobal.c | 795 |
1 files changed, 795 insertions, 0 deletions
diff --git a/private/ntos/mm/miglobal.c b/private/ntos/mm/miglobal.c new file mode 100644 index 000000000..e88e51f4a --- /dev/null +++ b/private/ntos/mm/miglobal.c @@ -0,0 +1,795 @@ +/*++ + +Copyright (c) 1989 Microsoft Corporation + +Module Name: + + miglobal.c + +Abstract: + + This module contains the private global storage for the memory + management subsystem. + +Author: + + Lou Perazzoli (loup) 6-Apr-1989 + +Revision History: + +--*/ +#include "mi.h" + +// +// Number of colors for pages in the system. +// + +ULONG MmNumberOfColors; + +// +// Number of secondary colcors, based on level 2 d cache size. +// + +ULONG MmSecondaryColors; + +// +// The starting color index seed, incrmented at each process creation. +// + +ULONG MmProcessColorSeed = 0x12345678; + +// +// Total number of physical pages available on the system. +// + +ULONG MmNumberOfPhysicalPages; + +// +// Lowest physical page number on the system. +// + +ULONG MmLowestPhysicalPage = 0xFFFFFFFF; + +// +// Higest physical page number on the system. +// + +ULONG MmHighestPhysicalPage; + +// +// Total number of available pages on the system. This +// is the sum of the pages on the zeroed, free and standby lists. +// + +ULONG MmAvailablePages ; +ULONG MmThrottleTop; +ULONG MmThrottleBottom; + +// +// System wide memory management statistics block. +// + +MMINFO_COUNTERS MmInfoCounters; + +// +// Total number phyisical pages which would be usable if every process +// was at it's minimum working set size. This value is initialized +// at system initialization to MmAvailablePages - MM_FLUID_PHYSICAL_PAGES. +// Everytime a thread is created, the kernel stack is subtracted from +// this and every time a process is created, the minimim working set +// is subtracted from this. If the value would become negative, the +// operation (create process/kernel stack/ adjust working set) fails. +// The PFN LOCK must be owned to manipulate this value. +// + +LONG MmResidentAvailablePages; + +// +// The total number of pages which would be removed from working sets +// if every working set was at its minimum. +// + +ULONG MmPagesAboveWsMinimum; + +// +// The total number of pages which would be removed from working sets +// if every working set above its maximum was at its maximum. +// + +ULONG MmPagesAboveWsMaximum; + +// +// The number of pages to add to a working set if there are ample +// available pages and the working set is below its maximum. +// + +// +// If memory is becoming short and MmPagesAboveWsMinimum is +// greater than MmPagesAboveWsThreshold, trim working sets. +// + +ULONG MmPagesAboveWsThreshold = 37; + +ULONG MmWorkingSetSizeIncrement = 6; + +// +// The number of pages to extend the maximum working set size by +// if the working set at its maximum and there are ample available pages. + +ULONG MmWorkingSetSizeExpansion = 20; + +// +// The number of pages required to be freed by working set reduction +// before working set reduction is attempted. +// + +ULONG MmWsAdjustThreshold = 45; + +// +// The number of pages available to allow the working set to be +// expanded above its maximum. +// + +ULONG MmWsExpandThreshold = 90; + +// +// The total number of pages to reduce by working set trimming. +// + +ULONG MmWsTrimReductionGoal = 29; + +PMMPFN MmPfnDatabase; + +MMPFNLIST MmZeroedPageListHead = { + 0, // Total + ZeroedPageList, // ListName + MM_EMPTY_LIST, //Flink + MM_EMPTY_LIST // Blink + }; + +MMPFNLIST MmFreePageListHead = { + 0, // Total + FreePageList, // ListName + MM_EMPTY_LIST, //Flink + MM_EMPTY_LIST // Blink + }; + +MMPFNLIST MmStandbyPageListHead = { + 0, // Total + StandbyPageList, // ListName + MM_EMPTY_LIST, //Flink + MM_EMPTY_LIST // Blink + }; + +MMPFNLIST MmModifiedPageListHead = { + 0, // Total + ModifiedPageList, // ListName + MM_EMPTY_LIST, //Flink + MM_EMPTY_LIST // Blink + }; + +MMPFNLIST MmModifiedNoWritePageListHead = { + 0, // Total + ModifiedNoWritePageList, // ListName + MM_EMPTY_LIST, //Flink + MM_EMPTY_LIST // Blink + }; + +MMPFNLIST MmBadPageListHead = { + 0, // Total + BadPageList, // ListName + MM_EMPTY_LIST, //Flink + MM_EMPTY_LIST // Blink + }; + +PMMPFNLIST MmPageLocationList[NUMBER_OF_PAGE_LISTS] = { + &MmZeroedPageListHead, + &MmFreePageListHead, + &MmStandbyPageListHead, + &MmModifiedPageListHead, + &MmModifiedNoWritePageListHead, + &MmBadPageListHead, + NULL, + NULL }; + + +// PMMPFNLIST MmPageLocationList[FreePageList] = &MmFreePageListHead; +// +// PMMPFNLIST MmPageLocationList[ZeroedPageList] = &MmZeroedPageListHead; +// +// PMMPFNLIST MmPageLocationList[StandbyPageList] = &MmStandbyPageListHead; +// +// PMMPFNLIST MmPageLocationList[ModifiedPageList] = &MmModifiedPageListHead; +// +// PMMPFNLIST MmPageLocationList[ModifiedNoWritePageList] = &MmModifiedNoWritePageListHead; +// +// PMMPFNLIST MmPageLocationList[BadPageList] = &MmBadPageListHead; +// +// PMMPFNLIST MmPageLocationList[ActiveAndValid] = NULL; +// +// PMMPFNLIST MmPageLocationList[TransitionPage] = NULL; + +// +// Hyper space items. +// + +PMMPTE MmFirstReservedMappingPte; + +PMMPTE MmLastReservedMappingPte; + +PMMWSL MmWorkingSetList; + +PMMWSLE MmWsle; + +// +// Event for available pages, set means pages are available. +// + +KEVENT MmAvailablePagesEvent; + +// +// Event for the zeroing page thread. +// + +KEVENT MmZeroingPageEvent; + +// +// Boolean to indicate if the zeroing page thread is currently +// active. This is set to true when the zeroing page event is +// set and set to false when the zeroing page thread is done +// zeroing all the pages on the free list. +// + +BOOLEAN MmZeroingPageThreadActive; + +// +// Minimum number of free pages before zeroing page thread starts. +// + +ULONG MmMinimumFreePagesToZero = 8; + +// +// System space sizes - MmNonPagedSystemStart to MM_NON_PAGED_SYSTEM_END +// defines the ranges of PDEs which must be copied into a new process's +// address space. +// + +PVOID MmNonPagedSystemStart; + +// +// Pool sizes. +// + +ULONG MmSizeOfNonPagedPoolInBytes; + +ULONG MmMaximumNonPagedPoolInBytes; + +ULONG MmMinimumNonPagedPoolSize = 256 * 1024; // 256k + +ULONG MmMinAdditionNonPagedPoolPerMb = 32 * 1024; // 32k + +ULONG MmDefaultMaximumNonPagedPool = 1024 * 1024; // 1mb + +ULONG MmMaxAdditionNonPagedPoolPerMb = 400 * 1024; //400k + +ULONG MmSizeOfPagedPoolInBytes = 32 * 1024 * 1024; // 32 MB. + +ULONG MmSizeOfNonPagedMustSucceed = 4 * PAGE_SIZE; // 4 pages + +ULONG MmNumberOfSystemPtes; + +ULONG MmLockLimitInBytes = 512 * 1024; + +ULONG MmLockPagesLimit; + +PMMPTE MmFirstPteForPagedPool; + +PMMPTE MmLastPteForPagedPool; + +PMMPTE MmPagedPoolBasePde; + +// +// Pool bit maps and other related structures. +// + +PRTL_BITMAP MmPagedPoolAllocationMap; + +PRTL_BITMAP MmEndOfPagedPoolBitmap; + +PVOID MmPageAlignedPoolBase[2]; + +PVOID MmNonPagedMustSucceed; + +ULONG MmExpandedPoolBitPosition; + +ULONG MmNumberOfFreeNonPagedPool; + +ULONG MmMustSucceedPoolBitPosition; + +// +// MmFirstFreeSystemPte contains the offset from the +// Nonpaged system base to the first free system PTE. +// Note, that an offset of FFFFF indicates an empty list. +// + +MMPTE MmFirstFreeSystemPte[MaximumPtePoolTypes]; + +PMMPTE MmNextPteForPagedPoolExpansion; + +// +// System cache sizes. +// + +PMMWSL MmSystemCacheWorkingSetList = (PMMWSL)MM_SYSTEM_CACHE_WORKING_SET; + +MMSUPPORT MmSystemCacheWs; + +PMMWSLE MmSystemCacheWsle; + +PVOID MmSystemCacheStart = (PVOID)MM_SYSTEM_CACHE_START; + +PVOID MmSystemCacheEnd; + +PRTL_BITMAP MmSystemCacheAllocationMap; + +PRTL_BITMAP MmSystemCacheEndingMap; + +ULONG MmSystemCacheBitMapHint; + +// +// This value should not be greater than 256MB in a system with 1GB of +// system space. +// + +ULONG MmSizeOfSystemCacheInPages = 64 * 256; //64MB. + +// +// Default sizes for the system cache. +// + +ULONG MmSystemCacheWsMinimum = 288; + +ULONG MmSystemCacheWsMaximum = 350; + +// +// Cells to track unused thread kernel stacks to avoid TB flushes +// every time a thread terminates. +// + +ULONG MmNumberDeadKernelStacks; +ULONG MmMaximumDeadKernelStacks = 5; +PMMPFN MmFirstDeadKernelStack = (PMMPFN)NULL; + +// +// MmSystemPteBase contains the address of 1 PTE before +// the first free system PTE (zero indicates an empty list). +// The value of this field does not change once set. +// + +PMMPTE MmSystemPteBase; + +PMMWSL MmWorkingSetList; + +PMMWSLE MmWsle; + +PMMADDRESS_NODE MmSectionBasedRoot; + +PVOID MmHighSectionBase = (PVOID)((ULONG)MM_HIGHEST_USER_ADDRESS - 0x800000); + +// +// Section object type. +// + +POBJECT_TYPE MmSectionObjectType; + +// +// Section commit mutex. +// + +FAST_MUTEX MmSectionCommitMutex; + +// +// Section base address mutex. +// + +FAST_MUTEX MmSectionBasedMutex; + +// +// Resource for section extension. +// + +ERESOURCE MmSectionExtendResource; +ERESOURCE MmSectionExtendSetResource; + +// +// Pagefile creation lock. +// + +FAST_MUTEX MmPageFileCreationLock; + +// +// Event to set when first paging file is created. +// + +PKEVENT MmPagingFileCreated; + +MMPTE GlobalPte; + +MMDEREFERENCE_SEGMENT_HEADER MmDereferenceSegmentHeader; + +LIST_ENTRY MmUnusedSegmentList; + +KEVENT MmUnusedSegmentCleanup; + +ULONG MmUnusedSegmentCount; + +// +// The maximum number of unused segments to accumulate before reduction +// begins. +// + +ULONG MmUnusedSegmentCountMaximum = 1000; + +// +// The number of unused segments to have when reduction is complete. +// + +ULONG MmUnusedSegmentCountGoal = 800; + +MMWORKING_SET_EXPANSION_HEAD MmWorkingSetExpansionHead; + +MMPAGE_FILE_EXPANSION MmAttemptForCantExtend; + +// +// Paging files +// + +MMMOD_WRITER_LISTHEAD MmPagingFileHeader; + +MMMOD_WRITER_LISTHEAD MmMappedFileHeader; + +PMMMOD_WRITER_MDL_ENTRY MmMappedFileMdl[MM_MAPPED_FILE_MDLS]; ; + +LIST_ENTRY MmFreePagingSpaceLow; + +ULONG MmNumberOfActiveMdlEntries; + +PMMPAGING_FILE MmPagingFile[MAX_PAGE_FILES]; + +ULONG MmNumberOfPagingFiles; + +KEVENT MmModifiedPageWriterEvent; + +KEVENT MmWorkingSetManagerEvent; + +KEVENT MmCollidedFlushEvent; + +// +// Total number of committed pages. +// + +ULONG MmTotalCommittedPages; + +// +// Limit on committed pages. When MmTotalComitttedPages would become +// greater than or equal to this number the paging files must be expanded. +// + +ULONG MmTotalCommitLimit; + +// +// Number of pages to overcommit without expanding the paging file. +// MmTotalCommitLimit = (total paging file space) + MmOverCommit. +// + +ULONG MmOverCommit; + +// +// Modified page writer. +// + + +// +// Minimum number of free pages before working set triming and +// aggressive modified page writing is started. +// + +ULONG MmMinimumFreePages = 26; + +// +// Stop writing modified pages when MmFreeGoal pages exist. +// + +ULONG MmFreeGoal = 100; + +// +// Start writing pages if more than this number of pages +// is on the modified page list. +// + +ULONG MmModifiedPageMaximum; + +// +// Minimum number of modified pages required before the modified +// page writer is started. +// + +ULONG MmModifiedPageMinimum; + +// +// Amount of disk space that must be free after the paging file is +// extended. +// + +ULONG MmMinimumFreeDiskSpace = 1024 * 1024; + +// +// Size to extend the paging file by. +// + +ULONG MmPageFileExtension = 128; //128 pages + +// +// Size to reduce the paging file by. +// + +ULONG MmMinimumPageFileReduction = 256; //256 pages (1mb) + +// +// Number of pages to write in a single I/O. +// + +ULONG MmModifiedWriteClusterSize = MM_MAXIMUM_WRITE_CLUSTER; + +// +// Number of pages to read in a single I/O if possible. +// + +ULONG MmReadClusterSize = 7; + +// +// Spin locks. +// + +// +// Spinlock which guards PFN database. This spinlock is used by +// memory mangement for accessing the PFN database. The I/O +// system makes use of it for unlocking pages during I/O complete. +// + +// KSPIN_LOCK MmPfnLock; + +// +// Spinlock which guards the working set list for the system shared +// address space (paged pool, system cache, pagable drivers). +// + +ERESOURCE MmSystemWsLock; + +PETHREAD MmSystemLockOwner; + +// +// Spin lock for allocating non-paged PTEs from system space. +// + +// KSPIN_LOCK MmSystemSpaceLock; + +// +// Spin lock for operating on page file commit charges. +// + +// KSPIN_LOCK MmChargeCommitmentLock; + +// +// Spin lock for allowing working set expansion. +// + +KSPIN_LOCK MmExpansionLock; + +// +// Spin lock for protecting hyper space access. +// + +// +// System process working set sizes. +// + +ULONG MmSystemProcessWorkingSetMin = 50; + +ULONG MmSystemProcessWorkingSetMax = 450; + +ULONG MmMaximumWorkingSetSize; + +ULONG MmMinimumWorkingSetSize = 20; + + +// +// Page color for system working set. +// + +ULONG MmSystemPageColor; + +// +// Time constants +// + +LARGE_INTEGER MmSevenMinutes = {0, -1}; + +// +// note that the following constant is initialized to five seconds, +// but is set to 3 on very small workstations. The constant used to +// be called MmFiveSecondsAbsolute, but since its value changes depending on +// the system type and size, I decided to change the name to reflect this +// +LARGE_INTEGER MmWorkingSetProtectionTime = {5 * 1000 * 1000 * 10, 0}; + +LARGE_INTEGER MmOneSecond = {(ULONG)(-1 * 1000 * 1000 * 10), -1}; +LARGE_INTEGER MmTwentySeconds = {(ULONG)(-20 * 1000 * 1000 * 10), -1}; +LARGE_INTEGER MmShortTime = {(ULONG)(-10 * 1000 * 10), -1}; // 10 milliseconds +LARGE_INTEGER MmHalfSecond = {(ULONG)(-5 * 100 * 1000 * 10), -1}; +LARGE_INTEGER Mm30Milliseconds = {(ULONG)(-30 * 1000 * 10), -1}; + +// +// Parameters for user mode passed up via PEB in MmCreatePeb +// +ULONG MmCritsectTimeoutSeconds = 2592000; +LARGE_INTEGER MmCriticalSectionTimeout; // Fill in by miinit.c +ULONG MmHeapSegmentReserve = 1024 * 1024; +ULONG MmHeapSegmentCommit = PAGE_SIZE * 2; +ULONG MmHeapDeCommitTotalFreeThreshold = 64 * 1024; +ULONG MmHeapDeCommitFreeBlockThreshold = PAGE_SIZE; + +// +// Set from ntos\config\CMDAT3.C Used by customers to disable paging +// of executive on machines with lots of memory. Worth a few TPS on a +// data base server. +// + +ULONG MmDisablePagingExecutive; + +#if DBG +ULONG MmDebug; +#endif + +// +// Map a page protection from the Pte.Protect field into a protection mask. +// + +ULONG MmProtectToValue[32] = { + PAGE_NOACCESS, + PAGE_READONLY, + PAGE_EXECUTE, + PAGE_EXECUTE_READ, + PAGE_READWRITE, + PAGE_WRITECOPY, + PAGE_EXECUTE_READWRITE, + PAGE_EXECUTE_WRITECOPY, + PAGE_NOACCESS, + PAGE_NOCACHE | PAGE_READONLY, + PAGE_NOCACHE | PAGE_EXECUTE, + PAGE_NOCACHE | PAGE_EXECUTE_READ, + PAGE_NOCACHE | PAGE_READWRITE, + PAGE_NOCACHE | PAGE_WRITECOPY, + PAGE_NOCACHE | PAGE_EXECUTE_READWRITE, + PAGE_NOCACHE | PAGE_EXECUTE_WRITECOPY, + PAGE_NOACCESS, + PAGE_GUARD | PAGE_READONLY, + PAGE_GUARD | PAGE_EXECUTE, + PAGE_GUARD | PAGE_EXECUTE_READ, + PAGE_GUARD | PAGE_READWRITE, + PAGE_GUARD | PAGE_WRITECOPY, + PAGE_GUARD | PAGE_EXECUTE_READWRITE, + PAGE_GUARD | PAGE_EXECUTE_WRITECOPY, + PAGE_NOACCESS, + PAGE_NOCACHE | PAGE_GUARD | PAGE_READONLY, + PAGE_NOCACHE | PAGE_GUARD | PAGE_EXECUTE, + PAGE_NOCACHE | PAGE_GUARD | PAGE_EXECUTE_READ, + PAGE_NOCACHE | PAGE_GUARD | PAGE_READWRITE, + PAGE_NOCACHE | PAGE_GUARD | PAGE_WRITECOPY, + PAGE_NOCACHE | PAGE_GUARD | PAGE_EXECUTE_READWRITE, + PAGE_NOCACHE | PAGE_GUARD | PAGE_EXECUTE_WRITECOPY + }; + +ULONG MmProtectToPteMask[32] = { + MM_PTE_NOACCESS, + MM_PTE_READONLY | MM_PTE_CACHE, + MM_PTE_EXECUTE | MM_PTE_CACHE, + MM_PTE_EXECUTE_READ | MM_PTE_CACHE, + MM_PTE_READWRITE | MM_PTE_CACHE, + MM_PTE_WRITECOPY | MM_PTE_CACHE, + MM_PTE_EXECUTE_READWRITE | MM_PTE_CACHE, + MM_PTE_EXECUTE_WRITECOPY | MM_PTE_CACHE, + MM_PTE_NOACCESS, + MM_PTE_NOCACHE | MM_PTE_READONLY, + MM_PTE_NOCACHE | MM_PTE_EXECUTE, + MM_PTE_NOCACHE | MM_PTE_EXECUTE_READ, + MM_PTE_NOCACHE | MM_PTE_READWRITE, + MM_PTE_NOCACHE | MM_PTE_WRITECOPY, + MM_PTE_NOCACHE | MM_PTE_EXECUTE_READWRITE, + MM_PTE_NOCACHE | MM_PTE_EXECUTE_WRITECOPY, + MM_PTE_NOACCESS, + MM_PTE_GUARD | MM_PTE_READONLY | MM_PTE_CACHE, + MM_PTE_GUARD | MM_PTE_EXECUTE | MM_PTE_CACHE, + MM_PTE_GUARD | MM_PTE_EXECUTE_READ | MM_PTE_CACHE, + MM_PTE_GUARD | MM_PTE_READWRITE | MM_PTE_CACHE, + MM_PTE_GUARD | MM_PTE_WRITECOPY | MM_PTE_CACHE, + MM_PTE_GUARD | MM_PTE_EXECUTE_READWRITE | MM_PTE_CACHE, + MM_PTE_GUARD | MM_PTE_EXECUTE_WRITECOPY | MM_PTE_CACHE, + MM_PTE_NOACCESS, + MM_PTE_NOCACHE | MM_PTE_GUARD | MM_PTE_READONLY, + MM_PTE_NOCACHE | MM_PTE_GUARD | MM_PTE_EXECUTE, + MM_PTE_NOCACHE | MM_PTE_GUARD | MM_PTE_EXECUTE_READ, + MM_PTE_NOCACHE | MM_PTE_GUARD | MM_PTE_READWRITE, + MM_PTE_NOCACHE | MM_PTE_GUARD | MM_PTE_WRITECOPY, + MM_PTE_NOCACHE | MM_PTE_GUARD | MM_PTE_EXECUTE_READWRITE, + MM_PTE_NOCACHE | MM_PTE_GUARD | MM_PTE_EXECUTE_WRITECOPY + }; + +// +// Conversion which takes a Pte.Protect and builds a new Pte.Protect which +// is not copy-on-write. +// + +ULONG MmMakeProtectNotWriteCopy[32] = { + MM_NOACCESS, + MM_READONLY, + MM_EXECUTE, + MM_EXECUTE_READ, + MM_READWRITE, + MM_READWRITE, //not copy + MM_EXECUTE_READWRITE, + MM_EXECUTE_READWRITE, + MM_NOACCESS, + MM_NOCACHE | MM_READONLY, + MM_NOCACHE | MM_EXECUTE, + MM_NOCACHE | MM_EXECUTE_READ, + MM_NOCACHE | MM_READWRITE, + MM_NOCACHE | MM_READWRITE, + MM_NOCACHE | MM_EXECUTE_READWRITE, + MM_NOCACHE | MM_EXECUTE_READWRITE, + MM_NOACCESS, + MM_GUARD_PAGE | MM_READONLY, + MM_GUARD_PAGE | MM_EXECUTE, + MM_GUARD_PAGE | MM_EXECUTE_READ, + MM_GUARD_PAGE | MM_READWRITE, + MM_GUARD_PAGE | MM_READWRITE, + MM_GUARD_PAGE | MM_EXECUTE_READWRITE, + MM_GUARD_PAGE | MM_EXECUTE_READWRITE, + MM_NOACCESS, + MM_NOCACHE | MM_GUARD_PAGE | MM_READONLY, + MM_NOCACHE | MM_GUARD_PAGE | MM_EXECUTE, + MM_NOCACHE | MM_GUARD_PAGE | MM_EXECUTE_READ, + MM_NOCACHE | MM_GUARD_PAGE | MM_READWRITE, + MM_NOCACHE | MM_GUARD_PAGE | MM_READWRITE, + MM_NOCACHE | MM_GUARD_PAGE | MM_EXECUTE_READWRITE, + MM_NOCACHE | MM_GUARD_PAGE | MM_EXECUTE_READWRITE + }; + +// +// Converts a protection code to an access right for section access. +// This uses on the lower 3 bits of the 5 bit protection code. +// + +ACCESS_MASK MmMakeSectionAccess[8] = { SECTION_MAP_READ, + SECTION_MAP_READ, + SECTION_MAP_EXECUTE, + SECTION_MAP_EXECUTE | SECTION_MAP_READ, + SECTION_MAP_WRITE, + SECTION_MAP_READ, + SECTION_MAP_EXECUTE | SECTION_MAP_WRITE, + SECTION_MAP_EXECUTE | SECTION_MAP_READ }; + +// +// Converts a protection code to an access right for file access. +// This uses on the lower 3 bits of the 5 bit protection code. +// + +ACCESS_MASK MmMakeFileAccess[8] = { FILE_READ_DATA, + FILE_READ_DATA, + FILE_EXECUTE, + FILE_EXECUTE | FILE_READ_DATA, + FILE_WRITE_DATA | FILE_READ_DATA, + FILE_READ_DATA, + FILE_EXECUTE | FILE_WRITE_DATA | FILE_READ_DATA, + FILE_EXECUTE | FILE_READ_DATA }; + |