[NTOSKRNL]
authorCameron Gutman <aicommander@gmail.com>
Wed, 30 Nov 2011 21:58:46 +0000 (21:58 +0000)
committerCameron Gutman <aicommander@gmail.com>
Wed, 30 Nov 2011 21:58:46 +0000 (21:58 +0000)
- Only flush pages if we can't satisfy Mm's target without using dirty pages

svn path=/trunk/; revision=54551

reactos/ntoskrnl/cc/view.c

index b8ce087..e93e914 100644 (file)
@@ -304,18 +304,15 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed)
     LIST_ENTRY FreeList;
     PFN_NUMBER Page;
     ULONG i;
+    BOOLEAN FlushedPages = FALSE;
 
     DPRINT("CcRosTrimCache(Target %d)\n", Target);
 
     InitializeListHead(&FreeList);
 
-    /* Flush dirty pages to disk */
-    CcRosFlushDirtyPages(Target, NrFreed);
-    
-    if ((*NrFreed) != 0) DPRINT1("Flushed %d dirty cache pages to disk\n", (*NrFreed));
-
     *NrFreed = 0;
 
+retry:
     KeAcquireGuardedMutex(&ViewLock);
 
     current_entry = CacheSegmentLRUListHead.Flink;
@@ -376,6 +373,25 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed)
 
     KeReleaseGuardedMutex(&ViewLock);
 
+    /* Try flushing pages if we haven't met our target */
+    if (Target > 0 && !FlushedPages)
+    {
+        /* Flush dirty pages to disk */
+        CcRosFlushDirtyPages(Target, &PagesFreed);
+        FlushedPages = TRUE;
+
+        /* We can only swap as many pages as we flushed */
+        if (PagesFreed < Target) Target = PagesFreed;
+
+        /* Check if we flushed anything */
+        if (PagesFreed != 0)
+        {
+            /* Try again after flushing dirty pages */
+            DPRINT1("Flushed %d dirty cache pages to disk\n", PagesFreed);
+            goto retry;
+        }
+    }
+
     while (!IsListEmpty(&FreeList))
     {
         current_entry = RemoveHeadList(&FreeList);