https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7e97071c8b715b16303ac7fa00be652b17f552ec

commit 7e97071c8b715b16303ac7fa00be652b17f552ec
Author:     Pierre Schweitzer <pie...@reactos.org>
AuthorDate: Sun Dec 23 14:43:17 2018 +0100
Commit:     Pierre Schweitzer <pie...@reactos.org>
CommitDate: Sun Dec 23 14:45:38 2018 +0100

    [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.
---
 ntoskrnl/cc/lazywrite.c        | 61 ++++++++++++++++++++++++++++++++++--------
 ntoskrnl/include/internal/cc.h |  2 +-
 2 files changed, 51 insertions(+), 12 deletions(-)

diff --git a/ntoskrnl/cc/lazywrite.c b/ntoskrnl/cc/lazywrite.c
index 8cb5adb2e7..275507e904 100644
--- a/ntoskrnl/cc/lazywrite.c
+++ b/ntoskrnl/cc/lazywrite.c
@@ -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())
diff --git a/ntoskrnl/include/internal/cc.h b/ntoskrnl/include/internal/cc.h
index 8a5fb73838..10bdb43a86 100644
--- a/ntoskrnl/include/internal/cc.h
+++ b/ntoskrnl/include/internal/cc.h
@@ -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;
 

Reply via email to