mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 16:36:33 +00:00
[NTOSKRNL] Reimplement the lazy writer in Cc and remove the "basic" one in Mm.
This removes the "modified page writer" thread in Mm that was regularly blindly attempting to flush dirty pages to the disk. Instead, this commit introduces a lazy writer that will monitor dirty pages count and will flush them to disk when this count is above a threshold. The threshold is computed on Cc init. Compared to what was done previously, this lazy writer will only write down files that are not marked as temporary. The mechanisms involved in this lazy writer worker are well described in Windows Internals 4th editions (constants are coming from it ;-)). Also fixed a bad (and old!) bug in CcRosFlushDirtyPages() where target count could be overflow and the function would spin forever while holding the VACBs lock. This is mandatory as now lazy writer will call it with "random" values. This also allows implementing CcWaitForCurrentLazyWriterActivity() :-). Also renamed DirtyPageCount to its MS equivalent. CORE-14235
This commit is contained in:
parent
2382435e88
commit
c7ad200f8b
9 changed files with 205 additions and 100 deletions
2
ntoskrnl/cache/newcc.h
vendored
2
ntoskrnl/cache/newcc.h
vendored
|
@ -53,7 +53,7 @@ CcMdlWriteComplete2(IN PFILE_OBJECT FileObject,
|
||||||
IN PLARGE_INTEGER FileOffset,
|
IN PLARGE_INTEGER FileOffset,
|
||||||
IN PMDL MdlChain);
|
IN PMDL MdlChain);
|
||||||
|
|
||||||
VOID
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
CcInitView(VOID);
|
CcInitView(VOID);
|
||||||
|
|
||||||
|
|
|
@ -41,8 +41,15 @@ NTAPI
|
||||||
INIT_FUNCTION
|
INIT_FUNCTION
|
||||||
CcInitializeCacheManager(VOID)
|
CcInitializeCacheManager(VOID)
|
||||||
{
|
{
|
||||||
CcInitView();
|
return CcInitView();
|
||||||
return TRUE;
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
CcShutdownSystem(VOID)
|
||||||
|
{
|
||||||
|
/* Inform the lazy writer it has to stop activity */
|
||||||
|
CcShutdownLazyWriter();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -34,6 +34,8 @@ ULONG CcFastReadWait;
|
||||||
ULONG CcFastReadNoWait;
|
ULONG CcFastReadNoWait;
|
||||||
ULONG CcFastReadResourceMiss;
|
ULONG CcFastReadResourceMiss;
|
||||||
|
|
||||||
|
extern KEVENT iLazyWriterNotify;
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -516,14 +518,26 @@ CcFastCopyWrite (
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
CcWaitForCurrentLazyWriterActivity (
|
CcWaitForCurrentLazyWriterActivity (
|
||||||
VOID)
|
VOID)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* Lazy writer is done when its event is set */
|
||||||
|
Status = KeWaitForSingleObject(&iLazyWriterNotify,
|
||||||
|
Executive,
|
||||||
|
KernelMode,
|
||||||
|
FALSE,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
/* GLOBALS *****************************************************************/
|
/* GLOBALS *****************************************************************/
|
||||||
|
|
||||||
extern KGUARDED_MUTEX ViewLock;
|
extern KGUARDED_MUTEX ViewLock;
|
||||||
extern ULONG DirtyPageCount;
|
extern ULONG CcTotalDirtyPages;
|
||||||
|
|
||||||
NTSTATUS CcRosInternalFreeVacb(PROS_VACB Vacb);
|
NTSTATUS CcRosInternalFreeVacb(PROS_VACB Vacb);
|
||||||
|
|
||||||
|
@ -239,7 +239,7 @@ CcPurgeCacheSection (
|
||||||
if (Vacb->Dirty)
|
if (Vacb->Dirty)
|
||||||
{
|
{
|
||||||
RemoveEntryList(&Vacb->DirtyVacbListEntry);
|
RemoveEntryList(&Vacb->DirtyVacbListEntry);
|
||||||
DirtyPageCount -= VACB_MAPPING_GRANULARITY / PAGE_SIZE;
|
CcTotalDirtyPages -= VACB_MAPPING_GRANULARITY / PAGE_SIZE;
|
||||||
}
|
}
|
||||||
RemoveEntryList(&Vacb->CacheMapVacbListEntry);
|
RemoveEntryList(&Vacb->CacheMapVacbListEntry);
|
||||||
InsertHeadList(&FreeList, &Vacb->CacheMapVacbListEntry);
|
InsertHeadList(&FreeList, &Vacb->CacheMapVacbListEntry);
|
||||||
|
|
|
@ -43,7 +43,6 @@
|
||||||
|
|
||||||
LIST_ENTRY DirtyVacbListHead;
|
LIST_ENTRY DirtyVacbListHead;
|
||||||
static LIST_ENTRY VacbLruListHead;
|
static LIST_ENTRY VacbLruListHead;
|
||||||
ULONG DirtyPageCount = 0;
|
|
||||||
|
|
||||||
KGUARDED_MUTEX ViewLock;
|
KGUARDED_MUTEX ViewLock;
|
||||||
|
|
||||||
|
@ -51,6 +50,27 @@ NPAGED_LOOKASIDE_LIST iBcbLookasideList;
|
||||||
static NPAGED_LOOKASIDE_LIST SharedCacheMapLookasideList;
|
static NPAGED_LOOKASIDE_LIST SharedCacheMapLookasideList;
|
||||||
static NPAGED_LOOKASIDE_LIST VacbLookasideList;
|
static NPAGED_LOOKASIDE_LIST VacbLookasideList;
|
||||||
|
|
||||||
|
/* Counters:
|
||||||
|
* - Amount of pages flushed by lazy writer
|
||||||
|
* - Number of times lazy writer ran
|
||||||
|
*/
|
||||||
|
ULONG CcLazyWritePages = 0;
|
||||||
|
ULONG CcLazyWriteIos = 0;
|
||||||
|
|
||||||
|
/* Internal vars (MS):
|
||||||
|
* - Threshold above which lazy writer will start action
|
||||||
|
* - Amount of dirty pages
|
||||||
|
*/
|
||||||
|
ULONG CcDirtyPageThreshold = 0;
|
||||||
|
ULONG CcTotalDirtyPages = 0;
|
||||||
|
|
||||||
|
/* Internal vars (ROS):
|
||||||
|
* - Event to notify lazy writer to shutdown
|
||||||
|
* - Event to inform watchers lazy writer is done for this loop
|
||||||
|
*/
|
||||||
|
KEVENT iLazyWriterShutdown;
|
||||||
|
KEVENT iLazyWriterNotify;
|
||||||
|
|
||||||
#if DBG
|
#if DBG
|
||||||
static void CcRosVacbIncRefCount_(PROS_VACB vacb, const char* file, int line)
|
static void CcRosVacbIncRefCount_(PROS_VACB vacb, const char* file, int line)
|
||||||
{
|
{
|
||||||
|
@ -145,7 +165,7 @@ CcRosFlushVacb (
|
||||||
|
|
||||||
Vacb->Dirty = FALSE;
|
Vacb->Dirty = FALSE;
|
||||||
RemoveEntryList(&Vacb->DirtyVacbListEntry);
|
RemoveEntryList(&Vacb->DirtyVacbListEntry);
|
||||||
DirtyPageCount -= VACB_MAPPING_GRANULARITY / PAGE_SIZE;
|
CcTotalDirtyPages -= VACB_MAPPING_GRANULARITY / PAGE_SIZE;
|
||||||
CcRosVacbDecRefCount(Vacb);
|
CcRosVacbDecRefCount(Vacb);
|
||||||
|
|
||||||
KeReleaseSpinLock(&Vacb->SharedCacheMap->CacheMapLock, oldIrql);
|
KeReleaseSpinLock(&Vacb->SharedCacheMap->CacheMapLock, oldIrql);
|
||||||
|
@ -160,7 +180,8 @@ NTAPI
|
||||||
CcRosFlushDirtyPages (
|
CcRosFlushDirtyPages (
|
||||||
ULONG Target,
|
ULONG Target,
|
||||||
PULONG Count,
|
PULONG Count,
|
||||||
BOOLEAN Wait)
|
BOOLEAN Wait,
|
||||||
|
BOOLEAN CalledFromLazy)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY current_entry;
|
PLIST_ENTRY current_entry;
|
||||||
PROS_VACB current;
|
PROS_VACB current;
|
||||||
|
@ -191,6 +212,14 @@ CcRosFlushDirtyPages (
|
||||||
|
|
||||||
CcRosVacbIncRefCount(current);
|
CcRosVacbIncRefCount(current);
|
||||||
|
|
||||||
|
/* When performing lazy write, don't handle temporary files */
|
||||||
|
if (CalledFromLazy &&
|
||||||
|
BooleanFlagOn(current->SharedCacheMap->FileObject->Flags, FO_TEMPORARY_FILE))
|
||||||
|
{
|
||||||
|
CcRosVacbDecRefCount(current);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
Locked = current->SharedCacheMap->Callbacks->AcquireForLazyWrite(
|
Locked = current->SharedCacheMap->Callbacks->AcquireForLazyWrite(
|
||||||
current->SharedCacheMap->LazyWriteContext, Wait);
|
current->SharedCacheMap->LazyWriteContext, Wait);
|
||||||
if (!Locked)
|
if (!Locked)
|
||||||
|
@ -239,8 +268,22 @@ CcRosFlushDirtyPages (
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
(*Count) += VACB_MAPPING_GRANULARITY / PAGE_SIZE;
|
ULONG PagesFreed;
|
||||||
Target -= VACB_MAPPING_GRANULARITY / PAGE_SIZE;
|
|
||||||
|
/* How many pages did we free? */
|
||||||
|
PagesFreed = VACB_MAPPING_GRANULARITY / PAGE_SIZE;
|
||||||
|
(*Count) += PagesFreed;
|
||||||
|
|
||||||
|
/* Make sure we don't overflow target! */
|
||||||
|
if (Target < PagesFreed)
|
||||||
|
{
|
||||||
|
/* If we would have, jump to zero directly */
|
||||||
|
Target = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Target -= PagesFreed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
current_entry = DirtyVacbListHead.Flink;
|
current_entry = DirtyVacbListHead.Flink;
|
||||||
|
@ -253,6 +296,60 @@ CcRosFlushDirtyPages (
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME: Someday this could somewhat implement write-behind/read-ahead */
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
CciLazyWriter(PVOID Unused)
|
||||||
|
{
|
||||||
|
LARGE_INTEGER OneSecond;
|
||||||
|
|
||||||
|
OneSecond.QuadPart = (LONGLONG)-1*1000*1000*10;
|
||||||
|
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
ULONG Target, Count = 0;
|
||||||
|
|
||||||
|
/* One per second or until we have to stop */
|
||||||
|
Status = KeWaitForSingleObject(&iLazyWriterShutdown,
|
||||||
|
Executive,
|
||||||
|
KernelMode,
|
||||||
|
FALSE,
|
||||||
|
&OneSecond);
|
||||||
|
|
||||||
|
/* If we succeeed, we've to stop running! */
|
||||||
|
if (Status == STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We're not sleeping anymore */
|
||||||
|
KeClearEvent(&iLazyWriterNotify);
|
||||||
|
|
||||||
|
/* Only start operations if above threshold */
|
||||||
|
DPRINT("TS: %lu, Count: %lu\n", CcDirtyPageThreshold, CcTotalDirtyPages);
|
||||||
|
if (CcTotalDirtyPages > CcDirtyPageThreshold)
|
||||||
|
{
|
||||||
|
/* Our target is one-eighth of the dirty pages */
|
||||||
|
Target = CcTotalDirtyPages / 8;
|
||||||
|
if (Target != 0)
|
||||||
|
{
|
||||||
|
/* Flush! */
|
||||||
|
DPRINT("Lazy writer starting (%d)\n", Target);
|
||||||
|
CcRosFlushDirtyPages(Target, &Count, FALSE, TRUE);
|
||||||
|
|
||||||
|
/* And update stats */
|
||||||
|
CcLazyWritePages += Count;
|
||||||
|
++CcLazyWriteIos;
|
||||||
|
DPRINT("Lazy writer done (%d)\n", Count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Inform people waiting on us that we're done */
|
||||||
|
KeSetEvent(&iLazyWriterNotify, IO_DISK_INCREMENT, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CcRosTrimCache (
|
CcRosTrimCache (
|
||||||
ULONG Target,
|
ULONG Target,
|
||||||
|
@ -346,7 +443,7 @@ retry:
|
||||||
if ((Target > 0) && !FlushedPages)
|
if ((Target > 0) && !FlushedPages)
|
||||||
{
|
{
|
||||||
/* Flush dirty pages to disk */
|
/* Flush dirty pages to disk */
|
||||||
CcRosFlushDirtyPages(Target, &PagesFreed, FALSE);
|
CcRosFlushDirtyPages(Target, &PagesFreed, FALSE, FALSE);
|
||||||
FlushedPages = TRUE;
|
FlushedPages = TRUE;
|
||||||
|
|
||||||
/* We can only swap as many pages as we flushed */
|
/* We can only swap as many pages as we flushed */
|
||||||
|
@ -403,7 +500,7 @@ CcRosReleaseVacb (
|
||||||
if (!WasDirty && Vacb->Dirty)
|
if (!WasDirty && Vacb->Dirty)
|
||||||
{
|
{
|
||||||
InsertTailList(&DirtyVacbListHead, &Vacb->DirtyVacbListEntry);
|
InsertTailList(&DirtyVacbListHead, &Vacb->DirtyVacbListEntry);
|
||||||
DirtyPageCount += VACB_MAPPING_GRANULARITY / PAGE_SIZE;
|
CcTotalDirtyPages += VACB_MAPPING_GRANULARITY / PAGE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Mapped)
|
if (Mapped)
|
||||||
|
@ -499,7 +596,7 @@ CcRosMarkDirtyVacb (
|
||||||
if (!Vacb->Dirty)
|
if (!Vacb->Dirty)
|
||||||
{
|
{
|
||||||
InsertTailList(&DirtyVacbListHead, &Vacb->DirtyVacbListEntry);
|
InsertTailList(&DirtyVacbListHead, &Vacb->DirtyVacbListEntry);
|
||||||
DirtyPageCount += VACB_MAPPING_GRANULARITY / PAGE_SIZE;
|
CcTotalDirtyPages += VACB_MAPPING_GRANULARITY / PAGE_SIZE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -552,7 +649,7 @@ CcRosUnmapVacb (
|
||||||
if (!WasDirty && NowDirty)
|
if (!WasDirty && NowDirty)
|
||||||
{
|
{
|
||||||
InsertTailList(&DirtyVacbListHead, &Vacb->DirtyVacbListEntry);
|
InsertTailList(&DirtyVacbListHead, &Vacb->DirtyVacbListEntry);
|
||||||
DirtyPageCount += VACB_MAPPING_GRANULARITY / PAGE_SIZE;
|
CcTotalDirtyPages += VACB_MAPPING_GRANULARITY / PAGE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
CcRosVacbDecRefCount(Vacb);
|
CcRosVacbDecRefCount(Vacb);
|
||||||
|
@ -1014,7 +1111,7 @@ CcRosDeleteFileCache (
|
||||||
if (current->Dirty)
|
if (current->Dirty)
|
||||||
{
|
{
|
||||||
RemoveEntryList(¤t->DirtyVacbListEntry);
|
RemoveEntryList(¤t->DirtyVacbListEntry);
|
||||||
DirtyPageCount -= VACB_MAPPING_GRANULARITY / PAGE_SIZE;
|
CcTotalDirtyPages -= VACB_MAPPING_GRANULARITY / PAGE_SIZE;
|
||||||
DPRINT1("Freeing dirty VACB\n");
|
DPRINT1("Freeing dirty VACB\n");
|
||||||
}
|
}
|
||||||
InsertHeadList(&FreeList, ¤t->CacheMapVacbListEntry);
|
InsertHeadList(&FreeList, ¤t->CacheMapVacbListEntry);
|
||||||
|
@ -1230,11 +1327,24 @@ CcGetFileObjectFromSectionPtrs (
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
NTAPI
|
||||||
|
CcShutdownLazyWriter (
|
||||||
|
VOID)
|
||||||
|
{
|
||||||
|
/* Simply set the event, lazy writer will stop when it's done */
|
||||||
|
KeSetEvent(&iLazyWriterShutdown, IO_DISK_INCREMENT, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
INIT_FUNCTION
|
INIT_FUNCTION
|
||||||
NTAPI
|
NTAPI
|
||||||
CcInitView (
|
CcInitView (
|
||||||
VOID)
|
VOID)
|
||||||
{
|
{
|
||||||
|
HANDLE LazyWriter;
|
||||||
|
NTSTATUS Status;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
|
||||||
DPRINT("CcInitView()\n");
|
DPRINT("CcInitView()\n");
|
||||||
|
|
||||||
InitializeListHead(&DirtyVacbListHead);
|
InitializeListHead(&DirtyVacbListHead);
|
||||||
|
@ -1264,7 +1374,50 @@ CcInitView (
|
||||||
|
|
||||||
MmInitializeMemoryConsumer(MC_CACHE, CcRosTrimCache);
|
MmInitializeMemoryConsumer(MC_CACHE, CcRosTrimCache);
|
||||||
|
|
||||||
|
/* Initialize lazy writer events */
|
||||||
|
KeInitializeEvent(&iLazyWriterShutdown, SynchronizationEvent, FALSE);
|
||||||
|
KeInitializeEvent(&iLazyWriterNotify, NotificationEvent, FALSE);
|
||||||
|
|
||||||
|
/* Define lazy writer threshold, depending on system type */
|
||||||
|
switch (MmQuerySystemSize())
|
||||||
|
{
|
||||||
|
case MmSmallSystem:
|
||||||
|
CcDirtyPageThreshold = MmNumberOfPhysicalPages / 8;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MmMediumSystem:
|
||||||
|
CcDirtyPageThreshold = MmNumberOfPhysicalPages / 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MmLargeSystem:
|
||||||
|
CcDirtyPageThreshold = MmNumberOfPhysicalPages / 8 + MmNumberOfPhysicalPages / 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Start the lazy writer thread */
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
NULL,
|
||||||
|
OBJ_KERNEL_HANDLE,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
Status = PsCreateSystemThread(&LazyWriter,
|
||||||
|
THREAD_ALL_ACCESS,
|
||||||
|
&ObjectAttributes,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
CciLazyWriter,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle is not needed */
|
||||||
|
ObCloseHandle(LazyWriter, KernelMode);
|
||||||
|
|
||||||
CcInitCacheZeroPage();
|
CcInitCacheZeroPage();
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -240,10 +240,14 @@ CcRosGetVacb(
|
||||||
PROS_VACB *Vacb
|
PROS_VACB *Vacb
|
||||||
);
|
);
|
||||||
|
|
||||||
VOID
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
CcInitView(VOID);
|
CcInitView(VOID);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
CcShutdownLazyWriter(VOID);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
CcReadVirtualAddress(PROS_VACB Vacb);
|
CcReadVirtualAddress(PROS_VACB Vacb);
|
||||||
|
@ -287,7 +291,8 @@ NTAPI
|
||||||
CcRosFlushDirtyPages(
|
CcRosFlushDirtyPages(
|
||||||
ULONG Target,
|
ULONG Target,
|
||||||
PULONG Count,
|
PULONG Count,
|
||||||
BOOLEAN Wait
|
BOOLEAN Wait,
|
||||||
|
BOOLEAN CalledFromLazy
|
||||||
);
|
);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -342,6 +347,10 @@ NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
CcTryToInitializeFileCache(PFILE_OBJECT FileObject);
|
CcTryToInitializeFileCache(PFILE_OBJECT FileObject);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
CcShutdownSystem(VOID);
|
||||||
|
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CcRosAcquireVacbLock(
|
CcRosAcquireVacbLock(
|
||||||
|
|
|
@ -19,9 +19,6 @@
|
||||||
|
|
||||||
VOID NTAPI MiInitializeUserPfnBitmap(VOID);
|
VOID NTAPI MiInitializeUserPfnBitmap(VOID);
|
||||||
|
|
||||||
HANDLE MpwThreadHandle;
|
|
||||||
KEVENT MpwThreadEvent;
|
|
||||||
|
|
||||||
BOOLEAN Mm64BitPhysicalAddress = FALSE;
|
BOOLEAN Mm64BitPhysicalAddress = FALSE;
|
||||||
ULONG MmReadClusterSize;
|
ULONG MmReadClusterSize;
|
||||||
//
|
//
|
||||||
|
@ -169,76 +166,6 @@ MiDbgDumpAddressSpace(VOID)
|
||||||
"Non Paged Pool Expansion PTE Space");
|
"Non Paged Pool Expansion PTE Space");
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
|
||||||
NTAPI
|
|
||||||
MmMpwThreadMain(PVOID Parameter)
|
|
||||||
{
|
|
||||||
NTSTATUS Status;
|
|
||||||
#ifndef NEWCC
|
|
||||||
ULONG PagesWritten;
|
|
||||||
#endif
|
|
||||||
LARGE_INTEGER Timeout;
|
|
||||||
|
|
||||||
UNREFERENCED_PARAMETER(Parameter);
|
|
||||||
|
|
||||||
Timeout.QuadPart = -50000000;
|
|
||||||
|
|
||||||
for(;;)
|
|
||||||
{
|
|
||||||
Status = KeWaitForSingleObject(&MpwThreadEvent,
|
|
||||||
0,
|
|
||||||
KernelMode,
|
|
||||||
FALSE,
|
|
||||||
&Timeout);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DbgPrint("MpwThread: Wait failed\n");
|
|
||||||
KeBugCheck(MEMORY_MANAGEMENT);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef NEWCC
|
|
||||||
PagesWritten = 0;
|
|
||||||
|
|
||||||
// XXX arty -- we flush when evicting pages or destorying cache
|
|
||||||
// sections.
|
|
||||||
CcRosFlushDirtyPages(128, &PagesWritten, FALSE);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
NTAPI
|
|
||||||
INIT_FUNCTION
|
|
||||||
MmInitMpwThread(VOID)
|
|
||||||
{
|
|
||||||
KPRIORITY Priority;
|
|
||||||
NTSTATUS Status;
|
|
||||||
CLIENT_ID MpwThreadId;
|
|
||||||
|
|
||||||
KeInitializeEvent(&MpwThreadEvent, SynchronizationEvent, FALSE);
|
|
||||||
|
|
||||||
Status = PsCreateSystemThread(&MpwThreadHandle,
|
|
||||||
THREAD_ALL_ACCESS,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
&MpwThreadId,
|
|
||||||
MmMpwThreadMain,
|
|
||||||
NULL);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
Priority = 27;
|
|
||||||
NtSetInformationThread(MpwThreadHandle,
|
|
||||||
ThreadPriority,
|
|
||||||
&Priority,
|
|
||||||
sizeof(Priority));
|
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
INIT_FUNCTION
|
INIT_FUNCTION
|
||||||
|
@ -338,11 +265,6 @@ MmInitSystem(IN ULONG Phase,
|
||||||
*/
|
*/
|
||||||
MiInitBalancerThread();
|
MiInitBalancerThread();
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialise the modified page writer.
|
|
||||||
*/
|
|
||||||
MmInitMpwThread();
|
|
||||||
|
|
||||||
/* Initialize the balance set manager */
|
/* Initialize the balance set manager */
|
||||||
MmInitBsmThread();
|
MmInitBsmThread();
|
||||||
|
|
||||||
|
|
|
@ -279,11 +279,10 @@ PopGracefulShutdown(IN PVOID Context)
|
||||||
CmShutdownSystem();
|
CmShutdownSystem();
|
||||||
|
|
||||||
/* Note that modified pages should be written here (MiShutdownSystem) */
|
/* Note that modified pages should be written here (MiShutdownSystem) */
|
||||||
#ifdef NEWCC
|
|
||||||
/* Flush all user files before we start shutting down IO */
|
/* Flush all user files before we start shutting down IO */
|
||||||
/* This is where modified pages are written back by the IO manager */
|
/* This is where modified pages are written back by the IO manager */
|
||||||
CcShutdownSystem();
|
CcShutdownSystem();
|
||||||
#endif
|
|
||||||
|
|
||||||
/* In this step, the I/O manager does last-chance shutdown notification */
|
/* In this step, the I/O manager does last-chance shutdown notification */
|
||||||
DPRINT("I/O manager shutting down in phase 1\n");
|
DPRINT("I/O manager shutting down in phase 1\n");
|
||||||
|
|
|
@ -952,7 +952,8 @@ NtSetSystemPowerState(IN POWER_ACTION SystemAction,
|
||||||
|
|
||||||
#ifndef NEWCC
|
#ifndef NEWCC
|
||||||
/* Flush dirty cache pages */
|
/* Flush dirty cache pages */
|
||||||
CcRosFlushDirtyPages(-1, &Dummy, FALSE); //HACK: We really should wait here!
|
/* XXX: Is that still mandatory? As now we'll wait on lazy writer to complete? */
|
||||||
|
CcRosFlushDirtyPages(-1, &Dummy, FALSE, FALSE); //HACK: We really should wait here!
|
||||||
#else
|
#else
|
||||||
Dummy = 0;
|
Dummy = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue