From 1f041b444485c5e6b302df49293ba1607075fe76 Mon Sep 17 00:00:00 2001 From: Dibyamartanda Samanta Date: Sat, 25 May 2024 10:15:26 +0200 Subject: [PATCH] Update NTOSKRNL/CC/cclazywriter.cpp --- NTOSKRNL/CC/cclazywriter.cpp | 89 +++++++++++++++++++++++++++++------- 1 file changed, 73 insertions(+), 16 deletions(-) diff --git a/NTOSKRNL/CC/cclazywriter.cpp b/NTOSKRNL/CC/cclazywriter.cpp index 33035ab..bfd7c0c 100644 --- a/NTOSKRNL/CC/cclazywriter.cpp +++ b/NTOSKRNL/CC/cclazywriter.cpp @@ -1019,7 +1019,74 @@ NTSTATUS CcWaitForCurrentLazyWriterActivity() return result; } +VOID VECTORCALL CcReEngageWorkerThreads( + ULONG NormalThreadsToActivate, + ULONG ExtraWriteBehindThreadsToActivate +) +{ + ULONG i; + PLIST_ENTRY currentThreadEntry; + PLIST_ENTRY nextThreadEntry; + ULONG j; + PLIST_ENTRY currentExtraThreadEntry; + PLIST_ENTRY nextExtraThreadEntry; + /*Activate the required number of normal worker threads*/ + for (i = 0; i < NormalThreadsToActivate; ++i) + { + + currentThreadEntry = CcIdleWorkerThreadList.Flink; + + if (IsListEmpty(&CcIdleWorkerThreadList)) + break; + nextThreadEntry = currentThreadEntry->Flink; + + /*Check if List is corrupt*/ + if (currentThreadEntry->Blink != &CcIdleWorkerThreadList || + nextThreadEntry->Blink != currentThreadEntry) + { + __fastfail(3u); + } + + /* Move to the next thread in the idle list*/ + ++CcNumberActiveWorkerThreads; + CcIdleWorkerThreadList.Flink = nextThreadEntry; + nextThreadEntry->Blink = &CcIdleWorkerThreadList; + /* Detach the current = thread from the list and schedule it for work*/ + currentThreadEntry->Flink = NULL; + ExQueueWorkItem(currentThreadEntry, CriticalWorkQueue); + } + + + + for (j = 0; j < ExtraWriteBehindThreadsToActivate; ++j) + { + /*first thread in the idle extra write-behind list*/ + currentExtraThreadEntry = CcIdleExtraWriteBehindThreadList.Flink; + + + if (IsListEmpty(&CcIdleExtraWriteBehindThreadList)) + break; + + nextExtraThreadEntry = currentExtraThreadEntry->Flink; + + /*Consistency check to prevent corrupt list operations*/ + if (currentExtraThreadEntry->Blink != &CcIdleExtraWriteBehindThreadList || + nextExtraThreadEntry->Blink != currentExtraThreadEntry) + { + __fastfail(3u); + } + + /* Move to the next thread in the idle extra list*/ + ++CcActiveExtraWriteBehindThreads; + CcIdleExtraWriteBehindThreadList.Flink = nextExtraThreadEntry; + nextExtraThreadEntry->Blink = &CcIdleExtraWriteBehindThreadList; + + /* Detach the current extra thread from the list and schedule it for work*/ + currentExtraThreadEntry->Flink = NULL; + ExQueueWorkItem(currentExtraThreadEntry, CriticalWorkQueue); + } +} VOID NTAPI CcWorkerThread(PVOID Parameter) @@ -1037,8 +1104,7 @@ CcWorkerThread(PVOID Parameter) DPRINT("CcWorkerThread: WorkItem"); - IoStatus.Status = STATUS_SUCCESS; - IoStatus.Information = 0; + /* Loop till we have jobs */ while (TRUE) @@ -1051,6 +1117,7 @@ CcWorkerThread(PVOID Parameter) { CcQueueThrottle = FALSE; DropThrottle = FALSE; + CcReEngageWorkerThreads(CcThreadsActiveBeforeThrottle, CcExtraThreadsActiveBeforeThrottle); } if (IoStatus.Information == 0x8A5E) @@ -1090,10 +1157,7 @@ CcWorkerThread(PVOID Parameter) break; } - /* Get our work item, if someone is waiting for us to finish - and we're not the only thread in queue then, quit running to let the others do - and throttle so that noone starts till current activity is over - */ + WorkEntry = CONTAINING_RECORD(Entry->Flink, WORK_QUEUE_ENTRY, WorkQueueLinks); if (WorkEntry->Function == SetDone && CcNumberActiveWorkerThreads > 1) @@ -1108,10 +1172,8 @@ CcWorkerThread(PVOID Parameter) /* Remove current entry */ RemoveHeadList(Entry); - /* Unlock queues */ KeReleaseQueuedSpinLock(LockQueueWorkQueueLock, OldIrql); - /* And handle it */ __try { switch (WorkEntry->Function) @@ -1149,11 +1211,9 @@ CcWorkerThread(PVOID Parameter) PsGetCurrentThread()->MemoryMaker = 0; } - /* Handle for WriteBehind */ if (IoStatus.Information == 0x8A5E) continue; - /* Release the current element and continue */ LookasideList = Prcb->PPLookasideList[5].P; InterlockedIncrement(&LookasideList->TotalFrees); // Use interlocked increment @@ -1183,21 +1243,18 @@ CcWorkerThread(PVOID Parameter) InterlockedIncrement(&LookasideList->FreeMisses); LookasideList->Free(WorkEntry); } - /* Our thread is available again */ + /* UNlock QUes*/ InsertTailList(&CcIdleWorkerThreadList, &WorkItem->List); - /* One less worker */ CcNumberActiveWorkerThreads--; /* Unlock queues */ KeReleaseQueuedSpinLock(LockQueueWorkQueueLock, OldIrql); - /* If there are pending write openations and we have at least 20 dirty pages */ + if (!IsListEmpty(&CcDeferredWrites) && CcTotalDirtyPages >= 20) { - /* And if we performed a write operation previously, - then stress the system a bit and reschedule a scan to find stuff to write - */ + if (WritePerformed) CcLazyWriteScan(); }