Update NTOSKRNL/CC/cclazywriter.cpp

This commit is contained in:
Dibyamartanda Samanta 2024-05-25 10:15:26 +02:00
parent 785ff4b644
commit 1f041b4444

View File

@ -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();
}