Author: sir_richard
Date: Sat Feb 20 22:48:36 2010
New Revision: 45638
URL:
http://svn.reactos.org/svn/reactos?rev=45638&view=rev
Log:
[NTOS]: Make MM init read MmProductType to determine what SKU of ReactOS this is, instead
of assuming Server. If you want to go back to the old behavior, you need to change
"WinNT" to "ServerNT" in the hivesys under Product Type.
[NTOS]: Configure the MmSystemSize variable properly based on SKU and RAM. Previously,
ReactOS told all drivers and applications you were running on a system with < 13MB
RAM.
[NTOS]: Initialize thresholds for low and high memory (in pages), low and high paged pool
memory, and low and high nonpaged pool memory. These are described in the source.
[NTOS]: Initialize events for each of those thresholds, and populate the
\KernelObject\xxxCondition events that are documented in MSDN for driver and app
developers.
[NTOS]: Define some internal thresholds to use later, representing the minimum number of
free pages under we go berserk, and the minimum number of free pages that we consider
"plenty".
[NTOS]: Rename MiRemoveFromList to MiUnlinkFreeOrZeroedPage (Windows name). Make the
function handle MmAvailablePages decrement, instead of having the caller do it.
[NTOS]: Remove run-time initialization of the PFN lists, just initialize them statically
(also fixes the fact we forgot to initialize their names).
[NTOS]: Move some more initialization code to ARM3 instead of mm.
[NTOS]: Read ProductType from registry into MmProductType instead of dummy value. Remove
duplicate "Mirroring" variable read.
Modified:
trunk/reactos/ntoskrnl/config/cmdata.c
trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c
trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
trunk/reactos/ntoskrnl/mm/ARM3/mminit.c
trunk/reactos/ntoskrnl/mm/ARM3/mmsup.c
trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c
trunk/reactos/ntoskrnl/mm/ARM3/pool.c
trunk/reactos/ntoskrnl/mm/freelist.c
trunk/reactos/ntoskrnl/mm/mminit.c
Modified: trunk/reactos/ntoskrnl/config/cmdata.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmdata.c?r…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmdata.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/config/cmdata.c [iso-8859-1] Sat Feb 20 22:48:36 2010
@@ -11,11 +11,12 @@
#include "ntoskrnl.h"
#define NDEBUG
#include "debug.h"
-
+
/* GLOBALS *******************************************************************/
ULONG DummyData;
ULONG CmNtGlobalFlag;
+extern ULONG MmProductType;
WCHAR CmDefaultLanguageId[12];
ULONG CmDefaultLanguageIdLength = sizeof(CmDefaultLanguageId);
@@ -266,14 +267,6 @@
{
L"Session Manager\\Memory Management",
- L"Mirroring",
- &DummyData,
- NULL,
- NULL
- },
-
- {
- L"Session Manager\\Memory Management",
L"SystemViewSize",
&DummyData,
NULL,
@@ -667,7 +660,7 @@
{
L"ProductOptions",
L"ProductType",
- &DummyData,
+ &MmProductType,
NULL,
NULL
},
Modified: trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/i386/init…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c [iso-8859-1] Sat Feb 20 22:48:36 2010
@@ -404,6 +404,9 @@
DPRINT("PFN DB PA PFN begins at: %lx\n", PageFrameIndex);
DPRINT("NP PA PFN begins at: %lx\n", PageFrameIndex + MxPfnAllocation);
+ /* Convert nonpaged pool size from bytes to pages */
+ MmMaximumNonPagedPoolInPages = MmMaximumNonPagedPoolInBytes >> PAGE_SHIFT;
+
//
// Now we need some pages to create the page tables for the NP system VA
// which includes system PTEs and expansion NP
@@ -496,10 +499,9 @@
ASSERT(MiAddressToPte(MmNonPagedSystemStart) <
MiAddressToPte(MmNonPagedPoolExpansionStart));
- //
- // Now go ahead and initialize the ARM³ nonpaged pool
- //
- MiInitializeArmPool();
+ /* Now go ahead and initialize the nonpaged pool */
+ MiInitializeNonPagedPool();
+ MiInitializeNonPagedPoolThresholds();
/* Map the PFN database pages */
MiMapPfnDatabase(LoaderBlock);
Modified: trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/miarm.h?r…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] Sat Feb 20 22:48:36 2010
@@ -168,6 +168,8 @@
extern ULONG MmSizeOfNonPagedPoolInBytes;
extern ULONG MmMaximumNonPagedPoolInBytes;
+extern PFN_NUMBER MmMaximumNonPagedPoolInPages;
+extern PFN_NUMBER MmSizeOfPagedPoolInPages;
extern PVOID MmNonPagedSystemStart;
extern PVOID MmNonPagedPoolStart;
extern PVOID MmNonPagedPoolExpansionStart;
@@ -217,6 +219,22 @@
extern ULONG MmMaximumNonPagedPoolPercent;
extern ULONG MmLargeStackSize;
extern PMMCOLOR_TABLES MmFreePagesByColor[FreePageList + 1];
+extern ULONG MmProductType;
+extern MM_SYSTEMSIZE MmSystemSize;
+extern PKEVENT MiLowMemoryEvent;
+extern PKEVENT MiHighMemoryEvent;
+extern PKEVENT MiLowPagedPoolEvent;
+extern PKEVENT MiHighPagedPoolEvent;
+extern PKEVENT MiLowNonPagedPoolEvent;
+extern PKEVENT MiHighNonPagedPoolEvent;
+extern PFN_NUMBER MmLowMemoryThreshold;
+extern PFN_NUMBER MmHighMemoryThreshold;
+extern PFN_NUMBER MiLowPagedPoolThreshold;
+extern PFN_NUMBER MiHighPagedPoolThreshold;
+extern PFN_NUMBER MiLowNonPagedPoolThreshold;
+extern PFN_NUMBER MiHighNonPagedPoolThreshold;
+extern PFN_NUMBER MmMinimumFreePages;
+extern PFN_NUMBER MmPlentyFreePages;
#define MI_PFN_TO_PFNENTRY(x) (&MmPfnDatabase[1][x])
#define MI_PFNENTRY_TO_PFN(x) (x - MmPfnDatabase[1])
@@ -258,6 +276,12 @@
IN PLOADER_PARAMETER_BLOCK LoaderBlock
);
+BOOLEAN
+NTAPI
+MiInitializeMemoryEvents(
+ VOID
+);
+
PFN_NUMBER
NTAPI
MxGetNextPage(
@@ -296,7 +320,19 @@
VOID
NTAPI
-MiInitializeArmPool(
+MiInitializeNonPagedPool(
+ VOID
+);
+
+VOID
+NTAPI
+MiInitializeNonPagedPoolThresholds(
+ VOID
+);
+
+VOID
+NTAPI
+MiInitializePoolEvents(
VOID
);
@@ -389,7 +425,7 @@
VOID
NTAPI
-MiRemoveFromList(
+MiUnlinkFreeOrZeroedPage(
IN PMMPFN Entry
);
Modified: trunk/reactos/ntoskrnl/mm/ARM3/mminit.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/mminit.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/mminit.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/mminit.c [iso-8859-1] Sat Feb 20 22:48:36 2010
@@ -25,6 +25,9 @@
ULONG MmMaximumNonPagedPoolPercent;
ULONG MmSizeOfNonPagedPoolInBytes;
ULONG MmMaximumNonPagedPoolInBytes;
+
+/* Some of the same values, in pages */
+PFN_NUMBER MmMaximumNonPagedPoolInPages;
//
// These numbers describe the discrete equation components of the nonpaged
@@ -257,6 +260,46 @@
*/
C_ASSERT(FreePageList == 1);
PMMCOLOR_TABLES MmFreePagesByColor[FreePageList + 1];
+
+/* An event used in Phase 0 before the rest of the system is ready to go */
+KEVENT MiTempEvent;
+
+/* All the events used for memory threshold notifications */
+PKEVENT MiLowMemoryEvent;
+PKEVENT MiHighMemoryEvent;
+PKEVENT MiLowPagedPoolEvent;
+PKEVENT MiHighPagedPoolEvent;
+PKEVENT MiLowNonPagedPoolEvent;
+PKEVENT MiHighNonPagedPoolEvent;
+
+/* The actual thresholds themselves, in page numbers */
+PFN_NUMBER MmLowMemoryThreshold;
+PFN_NUMBER MmHighMemoryThreshold;
+PFN_NUMBER MiLowPagedPoolThreshold;
+PFN_NUMBER MiHighPagedPoolThreshold;
+PFN_NUMBER MiLowNonPagedPoolThreshold;
+PFN_NUMBER MiHighNonPagedPoolThreshold;
+
+/*
+ * This number determines how many free pages must exist, at minimum, until we
+ * start trimming working sets and flushing modified pages to obtain more free
+ * pages.
+ *
+ * This number changes if the system detects that this is a server product
+ */
+PFN_NUMBER MmMinimumFreePages = 26;
+
+/*
+ * This number indicates how many pages we consider to be a low limit of having
+ * "plenty" of free memory.
+ *
+ * It is doubled on systems that have more than 63MB of memory
+ */
+PFN_NUMBER MmPlentyFreePages = 400;
+
+/* These values store the type of system this is (small, med, large) and if server */
+ULONG MmProductType;
+MM_SYSTEMSIZE MmSystemSize;
/* PRIVATE FUNCTIONS **********************************************************/
@@ -907,6 +950,217 @@
VOID
NTAPI
+MiAdjustWorkingSetManagerParameters(IN BOOLEAN Client)
+{
+ /* This function needs to do more work, for now, we tune page minimums */
+
+ /* Check for a system with around 64MB RAM or more */
+ if (MmNumberOfPhysicalPages >= (63 * _1MB) / PAGE_SIZE)
+ {
+ /* Double the minimum amount of pages we consider for a "plenty free"
scenario */
+ MmPlentyFreePages *= 2;
+ }
+}
+
+VOID
+NTAPI
+MiNotifyMemoryEvents(VOID)
+{
+ /* Are we in a low-memory situation? */
+ if (MmAvailablePages < MmLowMemoryThreshold)
+ {
+ /* Clear high, set low */
+ if (KeReadStateEvent(MiHighMemoryEvent)) KeClearEvent(MiHighMemoryEvent);
+ if (!KeReadStateEvent(MiLowMemoryEvent)) KeSetEvent(MiLowMemoryEvent, 0, FALSE);
+ }
+ else if (MmAvailablePages < MmHighMemoryThreshold)
+ {
+ /* We are in between, clear both */
+ if (KeReadStateEvent(MiHighMemoryEvent)) KeClearEvent(MiHighMemoryEvent);
+ if (KeReadStateEvent(MiLowMemoryEvent)) KeClearEvent(MiLowMemoryEvent);
+ }
+ else
+ {
+ /* Clear low, set high */
+ if (KeReadStateEvent(MiLowMemoryEvent)) KeClearEvent(MiLowMemoryEvent);
+ if (!KeReadStateEvent(MiHighMemoryEvent)) KeSetEvent(MiHighMemoryEvent, 0,
FALSE);
+ }
+}
+
+NTSTATUS
+NTAPI
+MiCreateMemoryEvent(IN PUNICODE_STRING Name,
+ OUT PKEVENT *Event)
+{
+ PACL Dacl;
+ HANDLE EventHandle;
+ ULONG DaclLength;
+ NTSTATUS Status;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ SECURITY_DESCRIPTOR SecurityDescriptor;
+
+ /* Create the SD */
+ Status = RtlCreateSecurityDescriptor(&SecurityDescriptor,
+ SECURITY_DESCRIPTOR_REVISION);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* One ACL with 3 ACEs, containing each one SID */
+ DaclLength = sizeof(ACL) +
+ 3 * sizeof(ACCESS_ALLOWED_ACE) +
+ RtlLengthSid(SeLocalSystemSid) +
+ RtlLengthSid(SeAliasAdminsSid) +
+ RtlLengthSid(SeWorldSid);
+
+ /* Allocate space for the DACL */
+ Dacl = ExAllocatePoolWithTag(PagedPool, DaclLength, 'lcaD');
+ if (!Dacl) return STATUS_INSUFFICIENT_RESOURCES;
+
+ /* Setup the ACL inside it */
+ Status = RtlCreateAcl(Dacl, DaclLength, ACL_REVISION);
+ if (!NT_SUCCESS(Status)) goto CleanUp;
+
+ /* Add query rights for everyone */
+ Status = RtlAddAccessAllowedAce(Dacl,
+ ACL_REVISION,
+ SYNCHRONIZE | EVENT_QUERY_STATE | READ_CONTROL,
+ SeWorldSid);
+ if (!NT_SUCCESS(Status)) goto CleanUp;
+
+ /* Full rights for the admin */
+ Status = RtlAddAccessAllowedAce(Dacl,
+ ACL_REVISION,
+ EVENT_ALL_ACCESS,
+ SeAliasAdminsSid);
+ if (!NT_SUCCESS(Status)) goto CleanUp;
+
+ /* As well as full rights for the system */
+ Status = RtlAddAccessAllowedAce(Dacl,
+ ACL_REVISION,
+ EVENT_ALL_ACCESS,
+ SeLocalSystemSid);
+ if (!NT_SUCCESS(Status)) goto CleanUp;
+
+ /* Set this DACL inside the SD */
+ Status = RtlSetDaclSecurityDescriptor(&SecurityDescriptor,
+ TRUE,
+ Dacl,
+ FALSE);
+ if (!NT_SUCCESS(Status)) goto CleanUp;
+
+ /* Setup the event attributes, making sure it's a permanent one */
+ InitializeObjectAttributes(&ObjectAttributes,
+ Name,
+ OBJ_KERNEL_HANDLE | OBJ_PERMANENT,
+ NULL,
+ &SecurityDescriptor);
+
+ /* Create the event */
+ Status = ZwCreateEvent(&EventHandle,
+ EVENT_ALL_ACCESS,
+ &ObjectAttributes,
+ NotificationEvent,
+ FALSE);
+CleanUp:
+ /* Free the DACL */
+ ExFreePool(Dacl);
+
+ /* Check if this is the success path */
+ if (NT_SUCCESS(Status))
+ {
+ /* Add a reference to the object, then close the handle we had */
+ Status = ObReferenceObjectByHandle(EventHandle,
+ EVENT_MODIFY_STATE,
+ ExEventObjectType,
+ KernelMode,
+ (PVOID*)Event,
+ NULL);
+ ZwClose (EventHandle);
+ }
+
+ /* Return status */
+ return Status;
+}
+
+BOOLEAN
+NTAPI
+MiInitializeMemoryEvents(VOID)
+{
+ UNICODE_STRING LowString =
RTL_CONSTANT_STRING(L"\\KernelObjects\\LowMemoryCondition");
+ UNICODE_STRING HighString =
RTL_CONSTANT_STRING(L"\\KernelObjects\\HighMemoryCondition");
+ UNICODE_STRING LowPagedPoolString =
RTL_CONSTANT_STRING(L"\\KernelObjects\\LowPagedPoolCondition");
+ UNICODE_STRING HighPagedPoolString =
RTL_CONSTANT_STRING(L"\\KernelObjects\\HighPagedPoolCondition");
+ UNICODE_STRING LowNonPagedPoolString =
RTL_CONSTANT_STRING(L"\\KernelObjects\\LowNonPagedPoolCondition");
+ UNICODE_STRING HighNonPagedPoolString =
RTL_CONSTANT_STRING(L"\\KernelObjects\\HighNonPagedPoolCondition");
+ NTSTATUS Status;
+
+ /* Check if we have a registry setting */
+ if (MmLowMemoryThreshold)
+ {
+ /* Convert it to pages */
+ MmLowMemoryThreshold *= (_1MB / PAGE_SIZE);
+ }
+ else
+ {
+ /* The low memory threshold is hit when we don't consider that we have
"plenty" of free pages anymore */
+ MmLowMemoryThreshold = MmPlentyFreePages;
+
+ /* More than one GB of memory? */
+ if (MmNumberOfPhysicalPages > 0x40000)
+ {
+ /* Start at 32MB, and add another 16MB for each GB */
+ MmLowMemoryThreshold = (32 * _1MB) / PAGE_SIZE;
+ MmLowMemoryThreshold += ((MmNumberOfPhysicalPages - 0x40000) >> 7);
+ }
+ else if (MmNumberOfPhysicalPages > 0x8000)
+ {
+ /* For systems with > 128MB RAM, add another 4MB for each 128MB */
+ MmLowMemoryThreshold += ((MmNumberOfPhysicalPages - 0x8000) >> 5);
+ }
+
+ /* Don't let the minimum threshold go past 64MB */
+ MmLowMemoryThreshold = min(MmLowMemoryThreshold, (64 * _1MB) / PAGE_SIZE);
+ }
+
+ /* Check if we have a registry setting */
+ if (MmHighMemoryThreshold)
+ {
+ /* Convert it into pages */
+ MmHighMemoryThreshold *= (_1MB / PAGE_SIZE);
+ }
+ else
+ {
+ /* Otherwise, the default is three times the low memory threshold */
+ MmHighMemoryThreshold = 3 * MmLowMemoryThreshold;
+ ASSERT(MmHighMemoryThreshold > MmLowMemoryThreshold);
+ }
+
+ /* Make sure high threshold is actually higher than the low */
+ MmHighMemoryThreshold = max(MmHighMemoryThreshold, MmLowMemoryThreshold);
+
+ /* Create the memory events for all the thresholds */
+ Status = MiCreateMemoryEvent(&LowString, &MiLowMemoryEvent);
+ if (!NT_SUCCESS(Status)) return FALSE;
+ Status = MiCreateMemoryEvent(&HighString, &MiHighMemoryEvent);
+ if (!NT_SUCCESS(Status)) return FALSE;
+ Status = MiCreateMemoryEvent(&LowPagedPoolString, &MiLowPagedPoolEvent);
+ if (!NT_SUCCESS(Status)) return FALSE;
+ Status = MiCreateMemoryEvent(&HighPagedPoolString, &MiHighPagedPoolEvent);
+ if (!NT_SUCCESS(Status)) return FALSE;
+ Status = MiCreateMemoryEvent(&LowNonPagedPoolString,
&MiLowNonPagedPoolEvent);
+ if (!NT_SUCCESS(Status)) return FALSE;
+ Status = MiCreateMemoryEvent(&HighNonPagedPoolString,
&MiHighNonPagedPoolEvent);
+ if (!NT_SUCCESS(Status)) return FALSE;
+
+ /* Now setup the pool events */
+ MiInitializePoolEvents();
+
+ /* Set the initial event state */
+ MiNotifyMemoryEvents();
+ return TRUE;
+}
+
+VOID
+NTAPI
MmDumpArmPfnDatabase(VOID)
{
ULONG i;
@@ -1324,10 +1578,14 @@
//
InitializePool(PagedPool, 0);
- //
- // Initialize the paged pool mutex
- //
- KeInitializeGuardedMutex(&MmPagedPoolMutex);
+ /* Default low threshold of 30MB or one fifth of paged pool */
+ MiLowPagedPoolThreshold = (30 * _1MB) >> PAGE_SHIFT;
+ MiLowPagedPoolThreshold = min(MiLowPagedPoolThreshold, Size / 5);
+
+ /* Default high threshold of 60MB or 25% */
+ MiHighPagedPoolThreshold = (60 * _1MB) >> PAGE_SHIFT;
+ MiHighPagedPoolThreshold = min(MiHighPagedPoolThreshold, (Size * 2) / 5);
+ ASSERT(MiLowPagedPoolThreshold < MiHighPagedPoolThreshold);
}
NTSTATUS
@@ -1353,6 +1611,17 @@
IncludeType[LoaderBBTMemory] = FALSE;
if (Phase == 0)
{
+ /* Initialize the phase 0 temporary event */
+ KeInitializeEvent(&MiTempEvent, NotificationEvent, FALSE);
+
+ /* Set all the events to use the temporary event for now */
+ MiLowMemoryEvent = &MiTempEvent;
+ MiHighMemoryEvent = &MiTempEvent;
+ MiLowPagedPoolEvent = &MiTempEvent;
+ MiHighPagedPoolEvent = &MiTempEvent;
+ MiLowNonPagedPoolEvent = &MiTempEvent;
+ MiHighNonPagedPoolEvent = &MiTempEvent;
+
//
// Define the basic user vs. kernel address space separation
//
@@ -1432,6 +1701,16 @@
//
MiSystemViewStart = (PVOID)((ULONG_PTR)MmSessionBase -
MmSystemViewSize);
+
+
+ /* Initialize the user mode image list */
+ InitializeListHead(&MmLoadedUserImageList);
+
+ /* Initialize the paged pool mutex */
+ KeInitializeGuardedMutex(&MmPagedPoolMutex);
+
+ /* Initialize the Loader Lock */
+ KeInitializeMutant(&MmSystemLoadLock, FALSE);
//
// Count physical pages on the system
@@ -1538,6 +1817,77 @@
// Size up paged pool and build the shadow system page directory
//
MiBuildPagedPool();
+
+ /* Check how many pages the system has */
+ if (MmNumberOfPhysicalPages <= (13 * _1MB))
+ {
+ /* Set small system */
+ MmSystemSize = MmSmallSystem;
+ }
+ else if (MmNumberOfPhysicalPages <= (19 * _1MB))
+ {
+ /* Set small system */
+ MmSystemSize = MmSmallSystem;
+ }
+ else
+ {
+ /* Set medium system */
+ MmSystemSize = MmMediumSystem;
+ }
+
+ /* Check for more than 32MB */
+ if (MmNumberOfPhysicalPages >= ((32 * _1MB) / PAGE_SIZE))
+ {
+ /* Check for product type being "Wi" for WinNT */
+ if (MmProductType == '\0i\0W')
+ {
+ /* Then this is a large system */
+ MmSystemSize = MmLargeSystem;
+ }
+ else
+ {
+ /* For servers, we need 64MB to consider this as being large */
+ if (MmNumberOfPhysicalPages >= ((64 * _1MB) / PAGE_SIZE))
+ {
+ /* Set it as large */
+ MmSystemSize = MmLargeSystem;
+ }
+ }
+ }
+
+ /* Now setup the shared user data fields */
+ ASSERT(SharedUserData->NumberOfPhysicalPages == 0);
+ SharedUserData->NumberOfPhysicalPages = MmNumberOfPhysicalPages;
+ SharedUserData->LargePageMinimum = 0;
+
+ /* Check for workstation (Wi for WinNT) */
+ if (MmProductType == '\0i\0W')
+ {
+ /* Set Windows NT Workstation product type */
+ SharedUserData->NtProductType = NtProductWinNt;
+ MmProductType = 0;
+ }
+ else
+ {
+ /* Check for LanMan server */
+ if (MmProductType == '\0a\0L')
+ {
+ /* This is a domain controller */
+ SharedUserData->NtProductType = NtProductLanManNt;
+ }
+ else
+ {
+ /* Otherwise it must be a normal server */
+ SharedUserData->NtProductType = NtProductServer;
+ }
+
+ /* Set the product type, and make the system more aggressive with low memory
*/
+ MmProductType = 1;
+ MmMinimumFreePages = 81;
+ }
+
+ /* Update working set tuning parameters */
+ MiAdjustWorkingSetManagerParameters(!MmProductType);
}
//
Modified: trunk/reactos/ntoskrnl/mm/ARM3/mmsup.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/mmsup.c?r…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/mmsup.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/mmsup.c [iso-8859-1] Sat Feb 20 22:48:36 2010
@@ -15,11 +15,6 @@
#line 15 "ARM³::MMSUP"
#define MODULE_INVOLVED_IN_ARM3
#include "../ARM3/miarm.h"
-
-/* GLOBALS ********************************************************************/
-
-BOOLEAN IsThisAnNtAsSystem = FALSE;
-MM_SYSTEMSIZE MmSystemSize = MmSmallSystem;
/* PUBLIC FUNCTIONS ***********************************************************/
@@ -137,10 +132,8 @@
NTAPI
MmIsThisAnNtAsSystem(VOID)
{
- //
- // Return if this is a server system
- //
- return IsThisAnNtAsSystem;
+ /* Return if this is a server system */
+ return MmProductType;
}
/*
@@ -150,9 +143,7 @@
NTAPI
MmQuerySystemSize(VOID)
{
- //
- // Return the low, medium or high memory system type
- //
+ /* Return the low, medium or high memory system type */
return MmSystemSize;
}
Modified: trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c [iso-8859-1] Sat Feb 20 22:48:36 2010
@@ -18,12 +18,25 @@
/* GLOBALS ********************************************************************/
-MMPFNLIST MmZeroedPageListHead;
-MMPFNLIST MmFreePageListHead;
-MMPFNLIST MmStandbyPageListHead;
-MMPFNLIST MmModifiedPageListHead;
-MMPFNLIST MmModifiedNoWritePageListHead;
-
+MMPFNLIST MmZeroedPageListHead = {0, ZeroedPageList, LIST_HEAD, LIST_HEAD};
+MMPFNLIST MmFreePageListHead = {0, FreePageList, LIST_HEAD, LIST_HEAD};
+MMPFNLIST MmStandbyPageListHead = {0, StandbyPageList, LIST_HEAD, LIST_HEAD};
+MMPFNLIST MmModifiedPageListHead = {0, ModifiedPageList, LIST_HEAD, LIST_HEAD};
+MMPFNLIST MmModifiedNoWritePageListHead = {0, ModifiedNoWritePageList, LIST_HEAD,
LIST_HEAD};
+MMPFNLIST MmBadPageListHead = {0, BadPageList, LIST_HEAD, LIST_HEAD};
+MMPFNLIST MmRomPageListHead = {0, StandbyPageList, LIST_HEAD, LIST_HEAD};
+
+PMMPFNLIST MmPageLocationList[] =
+{
+ &MmZeroedPageListHead,
+ &MmFreePageListHead,
+ &MmStandbyPageListHead,
+ &MmModifiedPageListHead,
+ &MmModifiedNoWritePageListHead,
+ &MmBadPageListHead,
+ NULL,
+ NULL
+};
/* FUNCTIONS ******************************************************************/
VOID
@@ -57,25 +70,28 @@
VOID
NTAPI
-MiRemoveFromList(IN PMMPFN Entry)
+MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry)
{
PFN_NUMBER OldFlink, OldBlink;
PMMPFNLIST ListHead;
-
- /* Find the list for this */
- if (Entry->u3.e1.PageLocation == ZeroedPageList)
- {
- ListHead = &MmZeroedPageListHead;
- }
- else if (Entry->u3.e1.PageLocation == FreePageList)
- {
- ListHead = &MmFreePageListHead;
- }
- else
- {
- ListHead = NULL;
- ASSERT(ListHead != NULL);
- }
+ MMLISTS ListName;
+
+ /* Make sure the PFN lock is held */
+ ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+
+ /* Make sure the PFN entry isn't in-use */
+ ASSERT(Entry->u3.e1.WriteInProgress == 0);
+ ASSERT(Entry->u3.e1.ReadInProgress == 0);
+
+ /* Find the list for this entry, make sure it's the free or zero list */
+ ListHead = MmPageLocationList[Entry->u3.e1.PageLocation];
+ ListName = ListHead->ListName;
+ ASSERT(ListHead != NULL);
+ ASSERT(ListName <= FreePageList);
+
+ /* Remove one count */
+ ASSERT(ListHead->Total != 0);
+ ListHead->Total--;
/* Get the forward and back pointers */
OldFlink = Entry->u1.Flink;
@@ -106,8 +122,27 @@
}
/* We are not on a list anymore */
- ListHead->Total--;
Entry->u1.Flink = Entry->u2.Blink = 0;
+
+ /* FIXME: Deal with color list */
+
+ /* 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 */
+ }
}
PMMPFN
Modified: trunk/reactos/ntoskrnl/mm/ARM3/pool.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pool.c?re…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/pool.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/pool.c [iso-8859-1] Sat Feb 20 22:48:36 2010
@@ -31,7 +31,97 @@
VOID
NTAPI
-MiInitializeArmPool(VOID)
+MiInitializeNonPagedPoolThresholds(VOID)
+{
+ PFN_NUMBER Size = MmMaximumNonPagedPoolInPages;
+
+ /* Default low threshold of 8MB or one third of nonpaged pool */
+ MiLowNonPagedPoolThreshold = (8 * _1MB) >> PAGE_SHIFT;
+ MiLowNonPagedPoolThreshold = min(MiLowNonPagedPoolThreshold, Size / 3);
+
+ /* Default high threshold of 20MB or 50% */
+ MiHighNonPagedPoolThreshold = (20 * _1MB) >> PAGE_SHIFT;
+ MiHighNonPagedPoolThreshold = min(MiHighNonPagedPoolThreshold, Size / 2);
+ ASSERT(MiLowNonPagedPoolThreshold < MiHighNonPagedPoolThreshold);
+}
+
+VOID
+NTAPI
+MiInitializePoolEvents(VOID)
+{
+ KIRQL OldIrql;
+ PFN_NUMBER FreePoolInPages;
+
+ /* Lock paged pool */
+ KeAcquireGuardedMutex(&MmPagedPoolMutex);
+
+ /* Total size of the paged pool minus the allocated size, is free */
+ FreePoolInPages = MmSizeOfPagedPoolInPages - MmPagedPoolInfo.AllocatedPagedPool;
+
+ /* Check the initial state high state */
+ if (FreePoolInPages >= MiHighPagedPoolThreshold)
+ {
+ /* We have plenty of pool */
+ KeSetEvent(MiHighPagedPoolEvent, 0, FALSE);
+ }
+ else
+ {
+ /* We don't */
+ KeClearEvent(MiHighPagedPoolEvent);
+ }
+
+ /* Check the initial low state */
+ if (FreePoolInPages <= MiLowPagedPoolThreshold)
+ {
+ /* We're very low in free pool memory */
+ KeSetEvent(MiLowPagedPoolEvent, 0, FALSE);
+ }
+ else
+ {
+ /* We're not */
+ KeClearEvent(MiLowPagedPoolEvent);
+ }
+
+ /* Release the paged pool lock */
+ KeReleaseGuardedMutex(&MmPagedPoolMutex);
+
+ /* Now it's time for the nonpaged pool lock */
+ OldIrql = KeAcquireQueuedSpinLock(LockQueueMmNonPagedPoolLock);
+
+ /* Free pages are the maximum minus what's been allocated */
+ FreePoolInPages = MmMaximumNonPagedPoolInPages - MmAllocatedNonPagedPool;
+
+ /* Check if we have plenty */
+ if (FreePoolInPages >= MiHighNonPagedPoolThreshold)
+ {
+ /* We do, set the event */
+ KeSetEvent(MiHighNonPagedPoolEvent, 0, FALSE);
+ }
+ else
+ {
+ /* We don't, clear the event */
+ KeClearEvent(MiHighNonPagedPoolEvent);
+ }
+
+ /* Check if we have very little */
+ if (FreePoolInPages <= MiLowNonPagedPoolThreshold)
+ {
+ /* We do, set the event */
+ KeSetEvent(MiLowNonPagedPoolEvent, 0, FALSE);
+ }
+ else
+ {
+ /* We don't, clear it */
+ KeClearEvent(MiLowNonPagedPoolEvent);
+ }
+
+ /* We're done, release the nonpaged pool lock */
+ KeReleaseQueuedSpinLock(LockQueueMmNonPagedPoolLock, OldIrql);
+}
+
+VOID
+NTAPI
+MiInitializeNonPagedPool(VOID)
{
ULONG i;
PFN_NUMBER PoolPages;
Modified: trunk/reactos/ntoskrnl/mm/freelist.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/freelist.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/freelist.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/freelist.c [iso-8859-1] Sat Feb 20 22:48:36 2010
@@ -245,14 +245,9 @@
do
{
//
- // One less free page
- //
- MmAvailablePages--;
-
- //
// This PFN is now a used page, set it up
//
- MiRemoveFromList(Pfn1);
+ MiUnlinkFreeOrZeroedPage(Pfn1);
Pfn1->u3.e2.ReferenceCount = 1;
//
@@ -638,12 +633,6 @@
PMEMORY_ALLOCATION_DESCRIPTOR Md;
PLIST_ENTRY NextEntry;
ULONG NrSystemPages = 0;
-
- /* Initialize the page lists */
- MmFreePageListHead.Flink = MmFreePageListHead.Blink = LIST_HEAD;
- MmZeroedPageListHead.Flink = MmZeroedPageListHead.Blink = LIST_HEAD;
- MmZeroedPageListHead.Total = 0;
- MmFreePageListHead.Total = 0;
/* This is what a used page looks like */
RtlZeroMemory(&UsedPage, sizeof(UsedPage));
Modified: trunk/reactos/ntoskrnl/mm/mminit.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/mminit.c?rev=4…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/mminit.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/mminit.c [iso-8859-1] Sat Feb 20 22:48:36 2010
@@ -402,25 +402,11 @@
MiInitializeUserPfnBitmap();
MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory);
- /* Initialize the user mode image list */
- InitializeListHead(&MmLoadedUserImageList);
-
- /* Initialize the Loader Lock */
- KeInitializeMutant(&MmSystemLoadLock, FALSE);
-
/* Reload boot drivers */
MiReloadBootLoadedDrivers(LoaderBlock);
/* Initialize the loaded module list */
MiInitializeLoadedModuleList(LoaderBlock);
-
- /* Setup shared user data settings that NT does as well */
- ASSERT(SharedUserData->NumberOfPhysicalPages == 0);
- SharedUserData->NumberOfPhysicalPages = MmNumberOfPhysicalPages;
- SharedUserData->LargePageMinimum = 0;
-
- /* For now, we assume that we're always Server */
- SharedUserData->NtProductType = NtProductServer;
}
else if (Phase == 1)
{
@@ -454,6 +440,9 @@
TempPte.u.Hard.PageFrameNumber = PageFrameNumber;
*MmSharedUserDataPte = TempPte;
+ /* Setup the memory threshold events */
+ if (!MiInitializeMemoryEvents()) return FALSE;
+
/*
* Unmap low memory
*/