mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
[NTOSKRNL] Implement write behind in Cc
For now, this is just a split between scan and flush that were both done during lazy scan previously. Lazy scan shouldn't perform any write operation, but only queue a write behind operation. Our implementation is far from the original, as it seems our lazy scan should queue a write behind operation per shared cache map. Right now, we only perform global operation.
This commit is contained in:
parent
d5c74ae6fe
commit
7e97071c8b
2 changed files with 51 additions and 12 deletions
|
@ -109,15 +109,33 @@ CcScanDpc(
|
|||
}
|
||||
|
||||
/* And post it, it will be for lazy write */
|
||||
WorkItem->Function = LazyWrite;
|
||||
WorkItem->Function = LazyScan;
|
||||
CcPostWorkQueue(WorkItem, &CcRegularWorkQueue);
|
||||
}
|
||||
|
||||
VOID
|
||||
CcWriteBehind(VOID)
|
||||
{
|
||||
ULONG Target, Count;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
CcLazyWriteScan(VOID)
|
||||
{
|
||||
ULONG Target;
|
||||
ULONG Count;
|
||||
KIRQL OldIrql;
|
||||
PLIST_ENTRY ListEntry;
|
||||
LIST_ENTRY ToPost;
|
||||
|
@ -142,14 +160,15 @@ CcLazyWriteScan(VOID)
|
|||
Target = CcTotalDirtyPages / 8;
|
||||
if (Target != 0)
|
||||
{
|
||||
/* Flush! */
|
||||
DPRINT("Lazy writer starting (%d)\n", Target);
|
||||
CcRosFlushDirtyPages(Target, &Count, FALSE, TRUE);
|
||||
/* There is stuff to flush, schedule a write-behind operation */
|
||||
|
||||
/* And update stats */
|
||||
CcLazyWritePages += Count;
|
||||
++CcLazyWriteIos;
|
||||
DPRINT("Lazy writer done (%d)\n", Count);
|
||||
/* Allocate a work item */
|
||||
WorkItem = ExAllocateFromNPagedLookasideList(&CcTwilightLookasideList);
|
||||
if (WorkItem != NULL)
|
||||
{
|
||||
WorkItem->Function = WriteBehind;
|
||||
CcPostWorkQueue(WorkItem, &CcRegularWorkQueue);
|
||||
}
|
||||
}
|
||||
|
||||
/* Post items that were due for end of run */
|
||||
|
@ -208,7 +227,7 @@ CcWorkerThread(
|
|||
IN PVOID Parameter)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
BOOLEAN DropThrottle;
|
||||
BOOLEAN DropThrottle, WritePerformed;
|
||||
PWORK_QUEUE_ITEM Item;
|
||||
#if DBG
|
||||
PIRP TopLevel;
|
||||
|
@ -218,6 +237,8 @@ CcWorkerThread(
|
|||
Item = Parameter;
|
||||
/* And by default, don't touch throttle */
|
||||
DropThrottle = FALSE;
|
||||
/* No write performed */
|
||||
WritePerformed = FALSE;
|
||||
|
||||
#if DBG
|
||||
/* Top level IRP should be clean when started
|
||||
|
@ -285,7 +306,12 @@ CcWorkerThread(
|
|||
CcPerformReadAhead(WorkItem->Parameters.Read.FileObject);
|
||||
break;
|
||||
|
||||
case LazyWrite:
|
||||
case WriteBehind:
|
||||
CcWriteBehind();
|
||||
WritePerformed = TRUE;
|
||||
break;
|
||||
|
||||
case LazyScan:
|
||||
CcLazyWriteScan();
|
||||
break;
|
||||
|
||||
|
@ -309,6 +335,19 @@ CcWorkerThread(
|
|||
--CcNumberActiveWorkerThreads;
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
#if DBG
|
||||
/* Top level shouldn't have changed */
|
||||
if (TopLevel != IoGetTopLevelIrp())
|
||||
|
|
|
@ -278,7 +278,7 @@ typedef enum _WORK_QUEUE_FUNCTIONS
|
|||
{
|
||||
ReadAhead = 1,
|
||||
WriteBehind = 2,
|
||||
LazyWrite = 3,
|
||||
LazyScan = 3,
|
||||
SetDone = 4,
|
||||
} WORK_QUEUE_FUNCTIONS, *PWORK_QUEUE_FUNCTIONS;
|
||||
|
||||
|
|
Loading…
Reference in a new issue