[ros-diffs] [arty] 44290: Debug paths related to page reclamation and simplify balance to the core. Also remove some vestigal uses of PageOps.

arty at svn.reactos.org arty at svn.reactos.org
Thu Nov 26 23:50:51 CET 2009


Author: arty
Date: Thu Nov 26 23:50:50 2009
New Revision: 44290

URL: http://svn.reactos.org/svn/reactos?rev=44290&view=rev
Log:
Debug paths related to page reclamation and simplify balance to the core.
Also remove some vestigal uses of PageOps.

Modified:
    branches/arty-newcc/ntoskrnl/include/internal/newmm.h
    branches/arty-newcc/ntoskrnl/io/iomgr/device.c
    branches/arty-newcc/ntoskrnl/io/iomgr/iofunc.c
    branches/arty-newcc/ntoskrnl/io/iomgr/rawfs.c
    branches/arty-newcc/ntoskrnl/mm/anonmem.c
    branches/arty-newcc/ntoskrnl/mm/balance.c
    branches/arty-newcc/ntoskrnl/mm/freelist.c
    branches/arty-newcc/ntoskrnl/mm/mpw.c
    branches/arty-newcc/ntoskrnl/mm/rmap.c
    branches/arty-newcc/ntoskrnl/mm/section/data.c
    branches/arty-newcc/ntoskrnl/mm/section/image.c
    branches/arty-newcc/ntoskrnl/mm/section/io.c
    branches/arty-newcc/ntoskrnl/mm/section/pagefile.c

Modified: branches/arty-newcc/ntoskrnl/include/internal/newmm.h
URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/include/internal/newmm.h?rev=44290&r1=44289&r2=44290&view=diff
==============================================================================
--- branches/arty-newcc/ntoskrnl/include/internal/newmm.h [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/include/internal/newmm.h [iso-8859-1] Thu Nov 26 23:50:50 2009
@@ -260,7 +260,7 @@
 
 typedef struct _MM_SECTION_SEGMENT
 {
-    FAST_MUTEX Lock;		/* lock which protects the page directory */
+    KGUARDED_MUTEX Lock;		/* lock which protects the page directory */
 	PFILE_OBJECT FileObject;
     ULARGE_INTEGER RawLength;		/* length of the segment which is part of the mapped file */
     ULARGE_INTEGER Length;			/* absolute length of the segment */
@@ -1685,7 +1685,8 @@
 
 NTSTATUS
 NTAPI
-MiReadFilePage(PFILE_OBJECT FileObject, PLARGE_INTEGER Offset, PPFN_TYPE Page);
+MiReadFilePage
+(PFILE_OBJECT FileObject, PLARGE_INTEGER Offset, PPFN_TYPE Page, BOOLEAN Locked);
 
 VOID
 NTAPI
@@ -1743,11 +1744,15 @@
 
 VOID
 NTAPI
-MmLockSectionSegment(PMM_SECTION_SEGMENT Segment);
-
-VOID
-NTAPI
-MmUnlockSectionSegment(PMM_SECTION_SEGMENT Segment);
+_MmLockSectionSegment(PMM_SECTION_SEGMENT Segment, const char *file, int line);
+
+VOID
+NTAPI
+_MmUnlockSectionSegment(PMM_SECTION_SEGMENT Segment, const char *file, int line);
+
+#define MmLockSectionSegment(S)	_MmLockSectionSegment(S,__FILE__,__LINE__)
+
+#define MmUnlockSectionSegment(S) _MmUnlockSectionSegment(S,__FILE__,__LINE__)
 
 VOID
 MmspCompleteAndReleasePageOp(PMM_PAGEOP PageOp);

Modified: branches/arty-newcc/ntoskrnl/io/iomgr/device.c
URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/io/iomgr/device.c?rev=44290&r1=44289&r2=44290&view=diff
==============================================================================
--- branches/arty-newcc/ntoskrnl/io/iomgr/device.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/io/iomgr/device.c [iso-8859-1] Thu Nov 26 23:50:50 2009
@@ -1150,7 +1150,11 @@
     NTSTATUS Status;
 
     /* Make sure there's a VPB */
-    if (!FileSystemDeviceObject->Vpb) return STATUS_INVALID_PARAMETER;
+    if (!FileSystemDeviceObject->Vpb)
+	{
+		DPRINT1("STATUS_INVALID_PARAMETER\n");
+		return STATUS_INVALID_PARAMETER;
+	}
 
     /* Acquire it */
     IoAcquireVpbSpinLock(&OldIrql);
@@ -1182,6 +1186,7 @@
     else
     {
         /* Fail */
+		DPRINT1("STATUS_INVALID_PARAMETER\n");
         Status = STATUS_INVALID_PARAMETER;
     }
 

Modified: branches/arty-newcc/ntoskrnl/io/iomgr/iofunc.c
URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/io/iomgr/iofunc.c?rev=44290&r1=44289&r2=44290&view=diff
==============================================================================
--- branches/arty-newcc/ntoskrnl/io/iomgr/iofunc.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/io/iomgr/iofunc.c [iso-8859-1] Thu Nov 26 23:50:50 2009
@@ -278,6 +278,7 @@
     {
         /* Fail */
         ObDereferenceObject(FileObject);
+		DPRINT1("STATUS_INVALID_PARAMETER\n");
         return STATUS_INVALID_PARAMETER;
     }
 
@@ -1122,6 +1123,7 @@
         /* Check if CompletionFilter is valid */
         if (!CompletionFilter || (CompletionFilter & ~FILE_NOTIFY_VALID_MASK))
         {
+		DPRINT1("STATUS_INVALID_PARAMETER\n");
             return STATUS_INVALID_PARAMETER;
         }
     }
@@ -2050,6 +2052,7 @@
         /* Otherwise, this was async I/O without a byte offset, so fail */
         if (EventObject) ObDereferenceObject(EventObject);
         ObDereferenceObject(FileObject);
+		DPRINT1("STATUS_INVALID_PARAMETER\n");
         return STATUS_INVALID_PARAMETER;
     }
 
@@ -2424,6 +2427,7 @@
             (FileObject->CompletionContext))
         {
             /* Fail */
+		DPRINT1("STATUS_INVALID_PARAMETER\n");
             Status = STATUS_INVALID_PARAMETER;
         }
         else
@@ -2458,6 +2462,7 @@
                          */
                         ExFreePool(Context);
                         ObDereferenceObject(Queue);
+		DPRINT1("STATUS_INVALID_PARAMETER\n");
                         Status = STATUS_INVALID_PARAMETER;
                     }
                 }
@@ -2903,6 +2908,7 @@
         /* Otherwise, this was async I/O without a byte offset, so fail */
         if (EventObject) ObDereferenceObject(EventObject);
         ObDereferenceObject(FileObject);
+		DPRINT1("STATUS_INVALID_PARAMETER\n");
         return STATUS_INVALID_PARAMETER;
     }
 

Modified: branches/arty-newcc/ntoskrnl/io/iomgr/rawfs.c
URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/io/iomgr/rawfs.c?rev=44290&r1=44289&r2=44290&view=diff
==============================================================================
--- branches/arty-newcc/ntoskrnl/io/iomgr/rawfs.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/io/iomgr/rawfs.c [iso-8859-1] Thu Nov 26 23:50:50 2009
@@ -239,6 +239,7 @@
     else
     {
         /* Invalid create request */
+		DPRINT1("STATUS_INVALID_PARAMETER\n");
         Status = STATUS_INVALID_PARAMETER;
         Irp->IoStatus.Information = 0;
     }
@@ -435,6 +436,7 @@
         default:
 
             /* Fail */
+		DPRINT1("STATUS_INVALID_PARAMETER\n");
             Status = STATUS_INVALID_PARAMETER;
             break;
     }
@@ -576,6 +578,7 @@
             DeviceObject->AlignmentRequirement))
         {
             /* It's not, fail */
+		DPRINT1("STATUS_INVALID_PARAMETER\n");
             Status = STATUS_INVALID_PARAMETER;
         }
         else
@@ -848,6 +851,7 @@
         default:
 
             /* Fail it */
+		DPRINT1("STATUS_INVALID_PARAMETER\n");
             Status = STATUS_INVALID_PARAMETER;
             break;
     }

Modified: branches/arty-newcc/ntoskrnl/mm/anonmem.c
URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/anonmem.c?rev=44290&r1=44289&r2=44290&view=diff
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/anonmem.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/anonmem.c [iso-8859-1] Thu Nov 26 23:50:50 2009
@@ -377,13 +377,10 @@
    /*
     * Try to allocate a page
     */
-   Status = MmRequestPageMemoryConsumer(MC_USER, FALSE, &Page);
-   if (Status == STATUS_NO_MEMORY)
-   {
-      MmUnlockAddressSpace(AddressSpace);
-      Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page);
-      MmLockAddressSpace(AddressSpace);
-   }
+   MmUnlockAddressSpace(AddressSpace);
+   Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page);
+   MmLockAddressSpace(AddressSpace);
+
    if (!NT_SUCCESS(Status))
    {
       DPRINT1("MmRequestPageMemoryConsumer failed, status = %x\n", Status);

Modified: branches/arty-newcc/ntoskrnl/mm/balance.c
URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/balance.c?rev=44290&r1=44289&r2=44290&view=diff
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/balance.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/balance.c [iso-8859-1] Thu Nov 26 23:50:50 2009
@@ -32,18 +32,17 @@
 /* GLOBALS ******************************************************************/
 
 MM_MEMORY_CONSUMER MiMemoryConsumers[MC_MAXIMUM];
-static ULONG MiMinimumAvailablePages;
+static ULONG MiMinimumAvailablePages = 512;
 static ULONG MiNrTotalPages;
 static LIST_ENTRY AllocationListHead;
 static KSPIN_LOCK AllocationListLock;
-static ULONG MiPagesRequired = 0;
-static ULONG MiMinimumPagesPerRun = 10;
+static ULONG MiMinimumPagesPerRun = 128;
 
 static CLIENT_ID MiBalancerThreadId;
 static HANDLE MiBalancerThreadHandle = NULL;
 static KEVENT MiBalancerEvent;
+static KEVENT MiBalancerContinue;
 static KTIMER MiBalancerTimer;
-static LONG MiBalancerWork = 0;
 
 /* FUNCTIONS ****************************************************************/
 
@@ -67,7 +66,6 @@
    MiNrTotalPages = NrAvailablePages;
 
    /* Set up targets. */
-   MiMinimumAvailablePages = 64;
     if ((NrAvailablePages + NrSystemPages) >= 8192)
     {
         MiMemoryConsumers[MC_CACHE].PagesTarget = NrAvailablePages / 4 * 3;   
@@ -117,7 +115,7 @@
    if (MmGetReferenceCountPage(Page) == 1)
    {
       (void)InterlockedDecrementUL(&MiMemoryConsumers[Consumer].PagesUsed);
-      if (IsListEmpty(&AllocationListHead) || MmAvailablePages < MiMinimumAvailablePages)
+      if (IsListEmpty(&AllocationListHead))
       {
          KeReleaseSpinLock(&AllocationListLock, OldIrql);
          OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
@@ -129,7 +127,8 @@
          Entry = RemoveHeadList(&AllocationListHead);
          Request = CONTAINING_RECORD(Entry, MM_ALLOCATION_REQUEST, ListEntry);
          KeReleaseSpinLock(&AllocationListLock, OldIrql);
-         if(Consumer == MC_USER) MmRemoveLRUUserPage(Page);
+         if(Consumer == MC_USER || Consumer == MC_PPOOL) 
+			 MmRemoveLRUUserPage(Page);
          MiZeroPage(Page);
          Request->Page = Page;
          KeSetEvent(&Request->Event, IO_NO_INCREMENT, FALSE);
@@ -142,26 +141,6 @@
    }
 
    return(STATUS_SUCCESS);
-}
-
-VOID
-NTAPI
-MiTrimMemoryConsumer(ULONG Consumer)
-{
-   LONG Target;
-   ULONG NrFreedPages;
-
-   Target = MiMemoryConsumers[Consumer].PagesUsed -
-            MiMemoryConsumers[Consumer].PagesTarget;
-   if (Target < 1)
-   {
-      Target = 1;
-   }
-
-   if (MiMemoryConsumers[Consumer].Trim != NULL)
-   {
-      MiMemoryConsumers[Consumer].Trim(Target, 0, &NrFreedPages);
-   }
 }
 
 NTSTATUS
@@ -172,27 +151,35 @@
     NTSTATUS Status;
     
     (*NrFreedPages) = 0;
+	DPRINT("Trimming user memory (want %d)\n", Target);
     
     CurrentPage = MmGetLRUFirstUserPage();
     while (CurrentPage != 0 && Target > 0)
     {
         NextPage = MmGetLRUNextUserPage(CurrentPage);
-        
+
+		DPRINT("Page Out %x\n", CurrentPage);
         Status = MmPageOutPhysicalAddress(CurrentPage);
+		DPRINT("Done %x\n", Status);
         if (NT_SUCCESS(Status))
         {
-            DPRINT("Succeeded\n");
             Target--;
             (*NrFreedPages)++;
         }
         else if (Status == STATUS_PAGEFILE_QUOTA)
         {
-            MmRemoveLRUUserPage(CurrentPage);
-            MmInsertLRULastUserPage(CurrentPage);
+			MmRemoveLRUUserPage(CurrentPage);
+			MmInsertLRULastUserPage(CurrentPage);
+			return STATUS_SUCCESS;
         }
         
         CurrentPage = NextPage;
     }
+	if (CurrentPage)
+		MmDereferencePage(CurrentPage);
+	
+	DPRINT("Done: %d\n", NrFreedPages);
+
     return(STATUS_SUCCESS);
 }
 
@@ -205,14 +192,16 @@
    ULONG NrFreedPages;
    NTSTATUS Status;
 
-   Target = (MiMinimumAvailablePages - MmAvailablePages) + MiPagesRequired;
+   Target = (MiMinimumAvailablePages - MmAvailablePages);
    Target = max(Target, (LONG) MiMinimumPagesPerRun);
 
    for (i = 0; i < MC_MAXIMUM && Target > 0; i++)
    {
       if (MiMemoryConsumers[i].Trim != NULL)
       {
-         Status = MiMemoryConsumers[i].Trim(Target, 0, &NrFreedPages);
+		 DPRINT("Trimming %d\n");
+		 Status = MiMemoryConsumers[i].Trim(Target, 0, &NrFreedPages);
+		 DPRINT("Got %d pages\n", NrFreedPages);
          if (!NT_SUCCESS(Status))
          {
             KeBugCheck(MEMORY_MANAGEMENT);
@@ -226,7 +215,7 @@
 MiIsBalancerThread(VOID)
 {
    return MiBalancerThreadHandle != NULL &&
-          PsGetCurrentThread() == MiBalancerThreadId.UniqueThread;
+          PsGetCurrentThreadId() == MiBalancerThreadId.UniqueThread;
 }
 
 NTSTATUS
@@ -234,106 +223,67 @@
 MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait,
                             PPFN_TYPE AllocatedPage)
 {
-   ULONG OldUsed;
-   PFN_TYPE Page;
+   PFN_TYPE Page = 0;
    KIRQL OldIrql;
 
-   /*
-    * Make sure we don't exceed our individual target.
-    */
-   OldUsed = InterlockedIncrementUL(&MiMemoryConsumers[Consumer].PagesUsed);
-   if (OldUsed >= (MiMemoryConsumers[Consumer].PagesTarget - 1) &&
-         !MiIsBalancerThread())
-   {
-      if (!CanWait)
-      {
-         (void)InterlockedDecrementUL(&MiMemoryConsumers[Consumer].PagesUsed);
-         return(STATUS_NO_MEMORY);
-      }
-      MiTrimMemoryConsumer(Consumer);
+   (void)InterlockedIncrementUL(&MiMemoryConsumers[Consumer].PagesUsed);
+
+   if (!MiIsBalancerThread() && MmAvailablePages <= MiMinimumAvailablePages && CanWait)
+   {
+	   DPRINT("MmAvailablePages %d MiMinimumAvailablePages %d\n", 
+			   MmAvailablePages, MiMinimumAvailablePages);
+	   KeSetEvent(&MiBalancerEvent, IO_NO_INCREMENT, FALSE);
+	   KeWaitForSingleObject(&MiBalancerContinue, 0, KernelMode, FALSE, NULL);
    }
 
    /*
     * Allocate always memory for the non paged pool and for the pager thread.
     */
-   if ((Consumer == MC_NPPOOL) || (Consumer == MC_SYSTEM) || MiIsBalancerThread())
+   if ((Consumer == MC_NPPOOL) || 
+	   (Consumer == MC_SYSTEM) || 
+	   MiIsBalancerThread() ||
+	   (MmAvailablePages > MiMinimumAvailablePages))
    {
       OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
       Page = MmAllocPage(Consumer, 0);
       KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
-      if (Page == 0)
+      if (!Page && MiIsBalancerThread())
       {
+		  DPRINT1("Can't allocate for balancer: %d vs %d\n",
+				  MmAvailablePages, MiMinimumAvailablePages);
          KeBugCheck(NO_PAGES_AVAILABLE);
       }
-      *AllocatedPage = Page;
-      if (MmAvailablePages <= MiMinimumAvailablePages &&
-            MiBalancerThreadHandle != NULL)
-      {
-         KeSetEvent(&MiBalancerEvent, IO_NO_INCREMENT, FALSE);
-      }
-      return(STATUS_SUCCESS);
    }
 
    /*
     * Make sure we don't exceed global targets.
     */
-   if (MmAvailablePages <= MiMinimumAvailablePages)
-   {
-      MM_ALLOCATION_REQUEST Request;
-
-      if (!CanWait)
-      {
-         (void)InterlockedDecrementUL(&MiMemoryConsumers[Consumer].PagesUsed);
-         return(STATUS_NO_MEMORY);
-      }
-
-      /* Insert an allocation request. */
-      Request.Page = 0;
-
-      KeInitializeEvent(&Request.Event, NotificationEvent, FALSE);
-      (void)InterlockedIncrementUL(&MiPagesRequired);
-
-      KeAcquireSpinLock(&AllocationListLock, &OldIrql);
-
-      if (MiBalancerThreadHandle != NULL)
-      {
-         KeSetEvent(&MiBalancerEvent, IO_NO_INCREMENT, FALSE);
-      }
-      InsertTailList(&AllocationListHead, &Request.ListEntry);
-      KeReleaseSpinLock(&AllocationListLock, OldIrql);
-
-      KeWaitForSingleObject(&Request.Event,
-                            0,
-                            KernelMode,
-                            FALSE,
-                            NULL);
-
-      Page = Request.Page;
-      if (Page == 0)
-      {
-         KeBugCheck(NO_PAGES_AVAILABLE);
-      }
-      /* Update the Consumer */
-      MiGetPfnEntry(Page)->u3.e1.PageLocation = Consumer;
-      if(Consumer == MC_USER) MmInsertLRULastUserPage(Page);
-      *AllocatedPage = Page;
-      (void)InterlockedDecrementUL(&MiPagesRequired);
-      return(STATUS_SUCCESS);
-   }
-
-   /*
-    * Actually allocate the page.
-    */
-   OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
-   Page = MmAllocPage(Consumer, 0);
-   KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
-   if (Page == 0)
-   {
-      KeBugCheck(NO_PAGES_AVAILABLE);
-   }
-   if(Consumer == MC_USER) MmInsertLRULastUserPage(Page);
+   while (!Page)
+   {
+	   if (!MiIsBalancerThread() || CanWait)
+	   {
+		   KeSetEvent(&MiBalancerEvent, IO_NO_INCREMENT, FALSE);
+		   KeWaitForSingleObject(&MiBalancerContinue, 0, KernelMode, FALSE, NULL);
+	   }
+
+	   /*
+		* Actually allocate the page.
+		*/
+	   OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+	   Page = MmAllocPage(Consumer, 0);
+	   KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+	   
+	   if (!Page && !CanWait)
+	   {
+		   (void)InterlockedDecrementUL(&MiMemoryConsumers[Consumer].PagesUsed);
+		   return(STATUS_NO_MEMORY);
+	   }
+   }
+
+   if(Consumer == MC_USER || Consumer == MC_PPOOL)
+	   MmInsertLRULastUserPage(Page);
    *AllocatedPage = Page;
-
+   
    return(STATUS_SUCCESS);
 }
 
@@ -342,15 +292,11 @@
 {
    PVOID WaitObjects[2];
    NTSTATUS Status;
-   ULONG i;
-   ULONG NrFreedPages;
-   ULONG NrPagesUsed;
-   ULONG Target;
-   BOOLEAN ShouldRun;
-
 
    WaitObjects[0] = &MiBalancerEvent;
    WaitObjects[1] = &MiBalancerTimer;
+
+   ASSERT(MiIsBalancerThread());
 
    while (1)
    {
@@ -363,61 +309,8 @@
                                         NULL,
                                         NULL);
 
-      if (Status == STATUS_SUCCESS)
-      {
-         /* MiBalancerEvent */
-         while (MmAvailablePages < MiMinimumAvailablePages + 5)
-         {
-            for (i = 0; i < MC_MAXIMUM; i++)
-            {
-               if (MiMemoryConsumers[i].Trim != NULL)
-               {
-                  NrFreedPages = 0;
-                  Status = MiMemoryConsumers[i].Trim(MiMinimumPagesPerRun, 0, &NrFreedPages);
-                  if (!NT_SUCCESS(Status))
-                  {
-                     KeBugCheck(MEMORY_MANAGEMENT);
-                  }
-               }
-            }
-         }
-         InterlockedExchange(&MiBalancerWork, 0);
-      }
-      else if (Status == STATUS_SUCCESS + 1)
-      {
-         /* MiBalancerTimer */
-         ShouldRun = MmAvailablePages < MiMinimumAvailablePages + 5 ? TRUE : FALSE;
-         for (i = 0; i < MC_MAXIMUM; i++)
-         {
-            if (MiMemoryConsumers[i].Trim != NULL)
-            {
-               NrPagesUsed = MiMemoryConsumers[i].PagesUsed;
-               if (NrPagesUsed > MiMemoryConsumers[i].PagesTarget || ShouldRun)
-               {
-                  if (NrPagesUsed > MiMemoryConsumers[i].PagesTarget)
-                  {
-                     Target = max (NrPagesUsed - MiMemoryConsumers[i].PagesTarget,
-                                   MiMinimumPagesPerRun);
-                  }
-                  else
-                  {
-                     Target = MiMinimumPagesPerRun;
-                  }
-                  NrFreedPages = 0;
-                  Status = MiMemoryConsumers[i].Trim(Target, 0, &NrFreedPages);
-                  if (!NT_SUCCESS(Status))
-                  {
-                     KeBugCheck(MEMORY_MANAGEMENT);
-                  }
-               }
-            }
-         }
-      }
-      else
-      {
-         DPRINT1("KeWaitForMultipleObjects failed, status = %x\n", Status);
-         KeBugCheck(MEMORY_MANAGEMENT);
-      }
+	  MmRebalanceMemoryConsumers();
+	  KeSetEvent(&MiBalancerContinue, IO_NO_INCREMENT, FALSE);
    }
 }
 
@@ -437,6 +330,7 @@
 
 
    KeInitializeEvent(&MiBalancerEvent, SynchronizationEvent, FALSE);
+   KeInitializeEvent(&MiBalancerContinue, SynchronizationEvent, FALSE);
    KeInitializeTimerEx(&MiBalancerTimer, SynchronizationTimer);
    KeSetTimerEx(&MiBalancerTimer,
 #if defined(__GNUC__)

Modified: branches/arty-newcc/ntoskrnl/mm/freelist.c
URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/freelist.c?rev=44290&r1=44289&r2=44290&view=diff
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/freelist.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/freelist.c [iso-8859-1] Thu Nov 26 23:50:50 2009
@@ -116,7 +116,7 @@
    Page = MiGetPfnEntry(Pfn);
    ASSERT(Page);
    ASSERT(Page->Flags.Type == MM_PHYSICAL_PAGE_USED);
-   ASSERT(Page->Flags.Consumer == MC_USER);
+   ASSERT(Page->Flags.Consumer == MC_USER || Page->Flags.Consumer == MC_PPOOL);
    InsertTailList(&UserPageListHead, &Page->ListEntry);
    KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
 }
@@ -134,7 +134,7 @@
    Page = MiGetPfnEntry(PreviousPfn);
    ASSERT(Page);
    ASSERT(Page->Flags.Type == MM_PHYSICAL_PAGE_USED);
-   ASSERT(Page->Flags.Consumer == MC_USER);
+   ASSERT(Page->Flags.Consumer == MC_USER || Page->Flags.Consumer == MC_PPOOL);
    NextListEntry = (PLIST_ENTRY)Page->ListEntry.Flink;
    if (NextListEntry == &UserPageListHead)
    {

Modified: branches/arty-newcc/ntoskrnl/mm/mpw.c
URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/mpw.c?rev=44290&r1=44289&r2=44290&view=diff
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/mpw.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/mpw.c [iso-8859-1] Thu Nov 26 23:50:50 2009
@@ -17,7 +17,7 @@
 /* GLOBALS *******************************************************************/
 
 HANDLE MpwThreadHandle;
-static CLIENT_ID MpwThreadId;
+CLIENT_ID MpwThreadId;
 KEVENT MpwThreadEvent, MpwCompleteEvent;
 BOOLEAN MpwThreadShouldTerminate;
 

Modified: branches/arty-newcc/ntoskrnl/mm/rmap.c
URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/rmap.c?rev=44290&r1=44289&r2=44290&view=diff
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/rmap.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/rmap.c [iso-8859-1] Thu Nov 26 23:50:50 2009
@@ -32,6 +32,7 @@
 
 /* GLOBALS ******************************************************************/
 
+ULONG RmapPagingOut = 0;
 static FAST_MUTEX RmapListLock;
 static NPAGED_LOOKASIDE_LIST RmapLookasideList;
 
@@ -62,7 +63,7 @@
    ULONG Type;
    PVOID Address;
    PEPROCESS Process;
-   PMM_PAGEOP PageOp;
+   PMM_PAGEOP PageOp = NULL;
    ULONG Offset;
    NTSTATUS Status = STATUS_SUCCESS;
 
@@ -121,6 +122,7 @@
    {
 	  Offset = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress;
 
+#ifndef _NEWCC_
       /*
        * Get or create a pageop
        */
@@ -137,6 +139,7 @@
          }
          return(STATUS_UNSUCCESSFUL);
       }
+#endif
 
       /*
        * Release locks now we have a page op.
@@ -205,7 +208,7 @@
    ULONG Type;
    PVOID Address;
    PEPROCESS Process;
-   PMM_PAGEOP PageOp;
+   PMM_PAGEOP PageOp = NULL;
    ULONG Offset;
    NTSTATUS Status = STATUS_SUCCESS;
 
@@ -255,6 +258,7 @@
    {
 	  Offset = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress;
 
+#ifndef _NEWCC_
       /*
        * Get or create a pageop
        */
@@ -270,6 +274,7 @@
          }
          return(STATUS_UNSUCCESSFUL);
       }
+#endif
 
       /*
        * Release locks now we have a page op.
@@ -388,6 +393,8 @@
 {
    PMM_RMAP_ENTRY current_entry;
 
+   ASSERT(Page);
+
    ExAcquireFastMutex(&RmapListLock);
    current_entry = MmGetRmapListHeadPage(Page);
    if (current_entry == NULL)
@@ -409,6 +416,8 @@
 {
    PMM_RMAP_ENTRY current_entry;
 
+   ASSERT(Page);
+
    ExAcquireFastMutex(&RmapListLock);
    current_entry = MmGetRmapListHeadPage(Page);
    if (current_entry == NULL)
@@ -429,6 +438,8 @@
 MmIsDirtyPageRmap(PFN_TYPE Page)
 {
    PMM_RMAP_ENTRY current_entry;
+
+   ASSERT(Page);
 
    ExAcquireFastMutex(&RmapListLock);
    current_entry = MmGetRmapListHeadPage(Page);
@@ -459,6 +470,7 @@
    PMM_RMAP_ENTRY new_entry;
    ULONG PrevSize;
 
+   ASSERT(Page);
    Address = (PVOID)PAGE_ROUND_DOWN(Address);
 
    new_entry = ExAllocateFromNPagedLookasideList(&RmapLookasideList);
@@ -530,6 +542,8 @@
    PMM_RMAP_ENTRY previous_entry;
    PEPROCESS Process;
 
+   ASSERT(Page);
+
    ExAcquireFastMutex(&RmapListLock);
    current_entry = MmGetRmapListHeadPage(Page);
    if (current_entry == NULL)
@@ -567,6 +581,8 @@
              PVOID Address)
 {
    PMM_RMAP_ENTRY current_entry, previous_entry;
+
+   ASSERT(Page);
 
    ExAcquireFastMutex(&RmapListLock);
    previous_entry = NULL;

Modified: branches/arty-newcc/ntoskrnl/mm/section/data.c
URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/section/data.c?rev=44290&r1=44289&r2=44290&view=diff
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/section/data.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/section/data.c [iso-8859-1] Thu Nov 26 23:50:50 2009
@@ -122,18 +122,18 @@
 
 VOID
 NTAPI
-MmLockSectionSegment(PMM_SECTION_SEGMENT Segment)
-{
-   DPRINT("MmLockSectionSegment(%p)\n", Segment);
-   ExAcquireFastMutex(&Segment->Lock);
+_MmLockSectionSegment(PMM_SECTION_SEGMENT Segment, const char *file, int line)
+{
+	DPRINT("MmLockSectionSegment(%p,%s:%d)\n", Segment, file, line);
+	KeAcquireGuardedMutex(&Segment->Lock);
 }
 
 VOID
 NTAPI
-MmUnlockSectionSegment(PMM_SECTION_SEGMENT Segment)
-{
-   ExReleaseFastMutex(&Segment->Lock);
-   DPRINT("MmUnlockSectionSegment(%p)\n", Segment);
+_MmUnlockSectionSegment(PMM_SECTION_SEGMENT Segment, const char *file, int line)
+{
+	DPRINT("MmUnlockSectionSegment(%p,%s:%d)\n", Segment, file, line);
+	KeReleaseGuardedMutex(&Segment->Lock);
 }
 
 VOID
@@ -233,7 +233,7 @@
 
 NTSTATUS
 NTAPI
-MiReadFilePage(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, PPFN_TYPE Page)
+MiReadFilePage(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, PPFN_TYPE Page, BOOLEAN Locked)
 {
 	PFN_TYPE XPage;
 	NTSTATUS Status;
@@ -255,7 +255,8 @@
 		return Status;
 	}
 	
-	MmLockAddressSpace(MmGetKernelAddressSpace());
+	if (!Locked)
+		MmLockAddressSpace(MmGetKernelAddressSpace());
 	Status = MmCreateMemoryArea
 		(MmGetKernelAddressSpace(),
 		 MEMORY_AREA_VIRTUAL_MEMORY, 
@@ -271,7 +272,8 @@
 	if (!NT_SUCCESS(Status))
 	{
 		DPRINT1("STATUS_NO_MEMORY: %x\n", Status);
-		MmUnlockAddressSpace(MmGetKernelAddressSpace());
+		if (!Locked)
+			MmUnlockAddressSpace(MmGetKernelAddressSpace());
 		MmReleasePageMemoryConsumer(MC_USER, *Page);
 		return STATUS_NO_MEMORY;
 	}
@@ -280,13 +282,15 @@
 	if (!NT_SUCCESS(Status))
 	{
 		MmFreeMemoryArea(MmGetKernelAddressSpace(), TmpArea, NULL, NULL);
-		MmUnlockAddressSpace(MmGetKernelAddressSpace());
+		if (!Locked)
+			MmUnlockAddressSpace(MmGetKernelAddressSpace());
 		MmReleasePageMemoryConsumer(MC_USER, *Page);
 		DPRINT1("Status: %x\n", Status);
 		return Status;
 	}
 	
-	MmUnlockAddressSpace(MmGetKernelAddressSpace());
+	if (!Locked)
+		MmUnlockAddressSpace(MmGetKernelAddressSpace());
 
 	MiZeroPage(*Page);
 	Status = MiSimpleRead
@@ -298,11 +302,13 @@
 	
 	DPRINT("Read Status %x (Page %x)\n", Status, *Page);
 
-	MmLockAddressSpace(MmGetKernelAddressSpace());
+	if (!Locked)
+		MmLockAddressSpace(MmGetKernelAddressSpace());
 	MmDeleteVirtualMapping(NULL, PageBuf, FALSE, NULL, &XPage);
 	ASSERT(XPage == *Page);
 	MmFreeMemoryArea(MmGetKernelAddressSpace(), TmpArea, NULL, NULL);
-	MmUnlockAddressSpace(MmGetKernelAddressSpace());
+	if (!Locked)
+		MmUnlockAddressSpace(MmGetKernelAddressSpace());
 
 	if (!NT_SUCCESS(Status))
 	{
@@ -377,9 +383,11 @@
 		DPRINT("Reading at offset %08x%08x (relative %x)\n", TotalOffset.HighPart, TotalOffset.LowPart, Offset);
 	
 		MmUnlockSectionSegment(Segment);
-		MmUnlockAddressSpace(AddressSpace);
-		Status = MiReadFilePage(Segment->FileObject, &TotalOffset, &Page);
-		MmLockAddressSpace(AddressSpace);
+		if (!Locked)
+			MmUnlockAddressSpace(AddressSpace);
+		Status = MiReadFilePage(Segment->FileObject, &TotalOffset, &Page, Locked);
+		if (!Locked)
+			MmLockAddressSpace(AddressSpace);
 
 		if (!NT_SUCCESS(Status))
 		{
@@ -422,10 +430,23 @@
 		SWAPENTRY SwapEntry;
 
 		MmDeletePageFileMapping(Process, (PVOID)PAddress, &SwapEntry);
+		MmUnlockSectionSegment(Segment);
+		if (!Locked)
+			MmUnlockAddressSpace(AddressSpace);
 		Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page);
 		if (!NT_SUCCESS(Status))
 		{
 			ASSERT(FALSE);
+		}
+
+		MmLockSectionSegment(Segment);
+		
+		if (!Locked)
+			MmLockAddressSpace(AddressSpace);
+		if (!MmIsPageSwapEntry(Process, PAddress))
+		{
+			// Handled elsewhere
+			return STATUS_SUCCESS;
 		}
 
 		Status = MmReadFromSwapPage(SwapEntry, Page);
@@ -434,6 +455,7 @@
 			DPRINT1("MmReadFromSwapPage failed, status = %x\n", Status);
 			ASSERT(FALSE);
 		}
+
 		DPRINT("CreateVirtualMapping: %x -> %x\n", Address, Attributes);
 		Status = MmCreateVirtualMapping(Process,
 										Address,
@@ -568,17 +590,20 @@
 MiCopyFromUserPage(PFN_TYPE DestPage, PVOID SourceAddress)
 {
     PEPROCESS Process;
-    KIRQL Irql;
+    KIRQL PrimaryIrql, Irql;
     PVOID TempAddress;
     
     Process = PsGetCurrentProcess();
+	PrimaryIrql = KfRaiseIrql(DISPATCH_LEVEL);
     TempAddress = MiMapPageInHyperSpace(Process, DestPage, &Irql);
     if (TempAddress == NULL)
     {
+		KfLowerIrql(PrimaryIrql);
         return(STATUS_NO_MEMORY);
     }
     memcpy(TempAddress, SourceAddress, PAGE_SIZE);
     MiUnmapPageInHyperSpace(Process, TempAddress, Irql);
+	KfLowerIrql(PrimaryIrql);
     return(STATUS_SUCCESS);
 }
 
@@ -657,7 +682,9 @@
    /*
     * Allocate a page
     */
+   MmUnlockSectionSegment(Segment);
    Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &NewPage);
+
    if (!NT_SUCCESS(Status))
    {
       ASSERT(FALSE);
@@ -668,6 +695,15 @@
     * Copy the old page
     */
    MiCopyFromUserPage(NewPage, PAddress);
+
+   MmLockSectionSegment(Segment);
+   if (MmGetPfnForProcess(Process, PAddress) != OldPage)
+   {
+	   // Handled elsewhere
+	   MmReleasePageMemoryConsumer(MC_USER, NewPage);
+	   MmUnlockSectionSegment(Segment);
+	   return STATUS_SUCCESS;
+   }
 
    /*
     * Delete the old entry.
@@ -834,26 +870,39 @@
 		("Pulling zero pages for %08x%08x-%08x%08x\n",
 		 FileOffset.u.HighPart, FileOffset.u.LowPart,
 		 End.u.HighPart, End.u.LowPart);
+	
 	MmLockSectionSegment(Segment);
 	while (FileOffset.QuadPart < End.QuadPart)
 	{
 		PVOID Address;
 		ULONG Entry = MiGetPageEntrySectionSegment(Segment, &FileOffset);
+
 		if (Entry == 0)
 		{
+			MmUnlockSectionSegment(Segment);
+			MmUnlockAddressSpace(AddressSpace);
+
 			if (!NT_SUCCESS(MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page)))
 			{
-				MmUnlockSectionSegment(Segment);
-				MmUnlockAddressSpace(AddressSpace);
 				return STATUS_NO_MEMORY;
 			}
+
+			MmLockAddressSpace(AddressSpace);
+			MmLockSectionSegment(Segment);
 			Address = ((PCHAR)MemoryArea->StartingAddress) + FileOffset.QuadPart - FirstMapped.QuadPart;
-			MmCreateVirtualMapping(NULL, Address, PAGE_READWRITE, &Page, 1);
-			MmInsertRmap(Page, NULL, Address);
-			MiSetPageEntrySectionSegment(Segment, &FileOffset, MAKE_SSE(Page << PAGE_SHIFT, 1));
+
+			if (!MmIsPagePresent(NULL, Address) && MiGetPageEntrySectionSegment(Segment, &FileOffset) == Entry)
+			{
+				MmCreateVirtualMapping(NULL, Address, PAGE_READWRITE, &Page, 1);
+				MmInsertRmap(Page, NULL, Address);
+				MiSetPageEntrySectionSegment(Segment, &FileOffset, MAKE_SSE(Page << PAGE_SHIFT, 1));
+			}
+			else
+				MmReleasePageMemoryConsumer(MC_USER, Page);
 		}
 		FileOffset.QuadPart += PAGE_SIZE;
 	}
+
 	MmUnlockSectionSegment(Segment);
 	MmUnlockAddressSpace(AddressSpace);
 	return STATUS_SUCCESS;
@@ -1000,8 +1049,6 @@
 	  }
 
       MmReleasePageMemoryConsumer(MC_USER, Page);
-      PageOp->Status = STATUS_SUCCESS;
-      MmspCompleteAndReleasePageOp(PageOp);
       return(STATUS_SUCCESS);
    }
    else if (!Context.WasDirty && Context.Private && SwapEntry != 0)
@@ -1017,8 +1064,6 @@
          ASSERT(FALSE);
       }
       MmReleasePageMemoryConsumer(MC_USER, Page);
-      PageOp->Status = STATUS_SUCCESS;
-      MmspCompleteAndReleasePageOp(PageOp);
       return(STATUS_SUCCESS);
    }
 
@@ -1067,8 +1112,6 @@
             MiSetPageEntrySectionSegment(Context.Segment, &Context.Offset, Entry);
          }
          MmUnlockAddressSpace(AddressSpace);
-         PageOp->Status = STATUS_UNSUCCESSFUL;
-         MmspCompleteAndReleasePageOp(PageOp);
          return(STATUS_PAGEFILE_QUOTA);
       }
    }
@@ -1113,8 +1156,6 @@
          MiSetPageEntrySectionSegment(Context.Segment, &Context.Offset, Entry);
       }
       MmUnlockAddressSpace(AddressSpace);
-      PageOp->Status = STATUS_UNSUCCESSFUL;
-      MmspCompleteAndReleasePageOp(PageOp);
       return(STATUS_UNSUCCESSFUL);
    }
 
@@ -1143,8 +1184,6 @@
       MiSetPageEntrySectionSegment(Context.Segment, &Context.Offset, Entry);
    }
 
-   PageOp->Status = STATUS_SUCCESS;
-   MmspCompleteAndReleasePageOp(PageOp);
    return(STATUS_SUCCESS);
 }
 
@@ -1159,10 +1198,8 @@
    PROS_SECTION_OBJECT Section;
    PMM_SECTION_SEGMENT Segment;
    PFN_TYPE Page;
-   SWAPENTRY SwapEntry;
    ULONG Entry;
-   BOOLEAN Private;
-   NTSTATUS Status;
+   NTSTATUS Status = STATUS_SUCCESS;
    PFILE_OBJECT FileObject;
    PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
 
@@ -1183,83 +1220,38 @@
    /*
     * Get the section segment entry and the physical address.
     */
+   MmLockAddressSpace(AddressSpace);
+   MmLockSectionSegment(Segment);
+
    Entry = MiGetPageEntrySectionSegment(Segment, &Offset);
-   if (!MmIsPagePresent(Process, Address))
-   {
-      DPRINT1("Trying to page out not-present page at (%d,0x%.8X).\n",
-              Process ? Process->UniqueProcessId : 0, Address);
-      ASSERT(FALSE);
-   }
    Page = MmGetPfnForProcess(Process, Address);
-   SwapEntry = MmGetSavedSwapEntryPage(Page);
+
+   if (!Page)
+   {
+	   // Somebody else already paged it out
+	   MmUnlockSectionSegment(Segment);
+	   MmUnlockAddressSpace(AddressSpace);
+	   return STATUS_SUCCESS;
+   }
 
    /*
     * Check for a private (COWed) page.
     */
-   if (IS_SWAP_FROM_SSE(Entry) || PFN_FROM_SSE(Entry) != Page)
-   {
-      Private = TRUE;
+   if (!IS_SWAP_FROM_SSE(Entry) && PFN_FROM_SSE(Entry) == Page && MmIsDirtyPageRmap(Page))
+   {
+	   MmSetCleanAllRmaps(Page);
+	   DPRINT("MiWriteBackPage(%wZ,%08x%08x)\n", &FileObject->FileName, Offset.u.HighPart, Offset.u.LowPart);
+	   MmUnlockSectionSegment(Segment);
+	   MmUnlockAddressSpace(AddressSpace);
+	   Status = MiWriteBackPage(FileObject, &Offset, PAGE_SIZE, Page);
    }
    else
    {
-      Private = FALSE;
-   }
-
-   /*
-    * Speculatively set all mappings of the page to clean.
-    */
-   MmSetCleanAllRmaps(Page);
-
-   /*
-    * If this page was direct mapped from the cache then the cache manager
-    * will take care of writing it back to disk.
-    */
-   if (!Private)
-   {
-      ASSERT(SwapEntry == 0);
-	  DPRINT("MiWriteBackPage(%wZ,%08x%08x)\n", &FileObject->FileName, Offset.u.HighPart, Offset.u.LowPart);
-      Status = PageOp->Status = MiWriteBackPage(FileObject, &Offset, PAGE_SIZE, Page);
-      MmspCompleteAndReleasePageOp(PageOp);
-      return(Status);
-   }
-
-   /*
-    * If necessary, allocate an entry in the paging file for this page
-    */
-   if (SwapEntry == 0)
-   {
-      SwapEntry = MmAllocSwapPage();
-      if (SwapEntry == 0)
-      {
-         MmSetDirtyAllRmaps(Page);
-         PageOp->Status = STATUS_UNSUCCESSFUL;
-         MmspCompleteAndReleasePageOp(PageOp);
-         return(STATUS_PAGEFILE_QUOTA);
-      }
-      MmSetSavedSwapEntryPage(Page, SwapEntry);
-   }
-
-   /*
-    * Write the page to the pagefile
-    */
-   Status = MmWriteToSwapPage(SwapEntry, Page);
-   if (!NT_SUCCESS(Status))
-   {
-      DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n",
-              Status);
-      MmSetDirtyAllRmaps(Page);
-      PageOp->Status = STATUS_UNSUCCESSFUL;
-      MmspCompleteAndReleasePageOp(PageOp);
-      return(STATUS_UNSUCCESSFUL);
-   }
-
-   /*
-    * Otherwise we have succeeded.
-    */
-   DPRINT("MM: Wrote section page 0x%.8X to swap!\n", Page << PAGE_SHIFT);
-   PageOp->Status = STATUS_SUCCESS;
-   MmspCompleteAndReleasePageOp(PageOp);
-   return(STATUS_SUCCESS);
+	   MmUnlockAddressSpace(AddressSpace);
+	   MmUnlockSectionSegment(Segment);
+   }
+
+   return(Status);
 }
 
 NTSTATUS
@@ -1291,8 +1283,6 @@
 	Segment = MemoryArea->Data.SectionData.Segment;
 	ViewOffset.QuadPart = MemoryArea->Data.SectionData.ViewOffset.QuadPart;
 
-	MmLockSectionSegment(Segment);
-
 	Pages = ExAllocatePool
 		(NonPagedPool, 
 		 sizeof(PFN_TYPE) * 
@@ -1302,6 +1292,8 @@
 	{
 		ASSERT(FALSE);
 	}
+
+	MmLockSectionSegment(Segment);
 
 	for (PageAddress = BeginningAddress;
 		 PageAddress < EndingAddress;
@@ -1336,8 +1328,10 @@
 		{
 			DPRINT("MiWriteBackPage(%wZ,%08x%08x)\n", &Segment->FileObject->FileName, FileOffset.u.HighPart, FileOffset.u.LowPart);
 			Status = MiWriteBackPage(Segment->FileObject, &FileOffset, PAGE_SIZE, Page);
+			MmLockAddressSpace(AddressSpace);
 			MmUnlockPage(Page);
 			MmSetCleanAllRmaps(Page);
+			MmUnlockAddressSpace(AddressSpace);
 			if (!NT_SUCCESS(Status))
 			{
 				DPRINT1
@@ -1695,7 +1689,7 @@
        return(STATUS_NO_MEMORY);
    }
 
-   ExInitializeFastMutex(&Segment->Lock);
+   KeInitializeGuardedMutex(&Segment->Lock);
 
    Segment->ReferenceCount = 1;
    Section->Segment = Segment;
@@ -1713,7 +1707,7 @@
       /*
        * Set the lock before assigning the segment to the file object
        */
-      ExAcquireFastMutex(&Segment->Lock);
+      KeAcquireGuardedMutex(&Segment->Lock);
 
       DPRINT("Filling out Segment info (No previous data section)\n");
 	  ObReferenceObject(FileObject);

Modified: branches/arty-newcc/ntoskrnl/mm/section/image.c
URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/section/image.c?rev=44290&r1=44289&r2=44290&view=diff
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/section/image.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/section/image.c [iso-8859-1] Thu Nov 26 23:50:50 2009
@@ -233,14 +233,17 @@
 	Entry = MiGetPageEntrySectionSegment(Segment, &Offset);
 	HasSwapEntry = MmIsPageSwapEntry(Process, (PVOID)PAddress);
 
-	if (Entry == 0 && !HasSwapEntry && Offset.QuadPart < PAGE_ROUND_UP(Segment->RawLength.QuadPart))
+	if (Entry == 0 && !HasSwapEntry && 
+		(Offset.QuadPart < PAGE_ROUND_UP(Segment->RawLength.QuadPart)))
 	{
 		TotalOffset.QuadPart = Offset.QuadPart + Segment->Image.FileOffset/*.QuadPart*/;
 
 		MmUnlockSectionSegment(Segment);
-		MmUnlockAddressSpace(AddressSpace);
-		Status = MiReadFilePage(Section->FileObject, &TotalOffset, &Page);
-		MmLockAddressSpace(AddressSpace);
+		if (!Locked)
+			MmUnlockAddressSpace(AddressSpace);
+		Status = MiReadFilePage(Section->FileObject, &TotalOffset, &Page, Locked);
+		if (!Locked)
+			MmLockAddressSpace(AddressSpace);
 
 		if (!NT_SUCCESS(Status))
 		{
@@ -282,10 +285,15 @@
 
 		MmDeletePageFileMapping(Process, (PVOID)PAddress, &SwapEntry);
 
+		MmUnlockSectionSegment(Segment);
+		if (!Locked)
+			MmUnlockAddressSpace(AddressSpace);
 		Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page);
 		if (!NT_SUCCESS(Status))
 		{
-			ASSERT(FALSE);
+			if (!Locked)
+				MmLockAddressSpace(AddressSpace);
+			return Status;
 		}
 		DPRINT("Allocated page %x\n", Page);
 
@@ -296,6 +304,14 @@
 			ASSERT(FALSE);
 		}
 		MmLockAddressSpace(AddressSpace);
+		MmLockSectionSegment(Segment);
+		if (MmIsPagePresent(Process, Address))
+		{
+			// Handled elsewhere
+			MmReleasePageMemoryConsumer(MC_USER, Page);
+			MmUnlockSectionSegment(Segment);
+			return STATUS_SUCCESS;
+		}
 		Status = MmCreateVirtualMapping(Process,
 										Address,
 										Region->Protect,
@@ -335,16 +351,26 @@
 	 */
 	if (Segment->Image.Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
 	{
-		MmUnlockAddressSpace(AddressSpace);
+		MmUnlockSectionSegment(Segment);
+		if (!Locked)
+			MmUnlockAddressSpace(AddressSpace);
 		Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page);
 		if (!NT_SUCCESS(Status))
 		{
 			DPRINT("Status %x\n", Status);
-			MmUnlockSectionSegment(Segment);
+			if (!Locked)
+				MmLockAddressSpace(AddressSpace);
 			return Status;
 		}
 		DPRINT("Allocated page %x\n", Page);
-		MmLockAddressSpace(AddressSpace);
+		if (!Locked)
+			MmLockAddressSpace(AddressSpace);
+		if (MmIsPagePresent(Process, Address))
+		{
+			// Handled elsewhere
+			MmReleasePageMemoryConsumer(MC_USER, Page);
+			return STATUS_SUCCESS;
+		}
 		Status = MmCreateVirtualMapping(Process,
 										Address,
 										Region->Protect,
@@ -354,7 +380,6 @@
 		{
 			MmReleasePageMemoryConsumer(MC_USER, Page);
 			DPRINT("Release page %x\n", Page);
-			MmUnlockSectionSegment(Segment);
 			return(Status);
 		}
 		MmInsertRmap(Page, Process, (PVOID)PAddress);
@@ -366,7 +391,6 @@
 		/*
 		 * Cleanup and release locks
 		 */
-		MmUnlockSectionSegment(Segment);
 		//DPRINT("Address 0x%.8X\n", Address);
 		return(STATUS_SUCCESS);
 	}
@@ -386,7 +410,9 @@
 		/*
 		 * Release all our locks and read in the page from disk
 		 */
-		MmUnlockAddressSpace(AddressSpace);
+		MmUnlockSectionSegment(Segment);
+		if (!Locked)
+			MmUnlockAddressSpace(AddressSpace);
 
 		if (Offset.QuadPart >= PAGE_ROUND_UP(Segment->RawLength.QuadPart))
 		{
@@ -394,8 +420,8 @@
 			if (!NT_SUCCESS(Status))
 			{
 				DPRINT1("MmRequestPageMemoryConsumer failed (Status %x)\n", Status);
-				MmLockAddressSpace(AddressSpace);
-				MmUnlockSectionSegment(Segment);
+				if (!Locked)
+					MmLockAddressSpace(AddressSpace);
 				return Status;
 			}
 			DPRINT("Allocated page %x\n", Page);
@@ -409,8 +435,8 @@
 				DPRINT1("Unable to create virtual mapping\n");
 				MmReleasePageMemoryConsumer(MC_USER, Page);
 				DPRINT("Release page %x\n", Page);
-				MmLockAddressSpace(AddressSpace);
-				MmUnlockSectionSegment(Segment);
+				if (!Locked)
+					MmLockAddressSpace(AddressSpace);
 				return Status;
 			}
 		}
@@ -426,8 +452,8 @@
 				DPRINT1("Unable to create virtual mapping\n");
 				MmReleasePageMemoryConsumer(MC_USER, Page);
 				DPRINT("Release page %x\n", Page);
-				MmLockAddressSpace(AddressSpace);
-				MmUnlockSectionSegment(Segment);
+				if (!Locked)
+					MmLockAddressSpace(AddressSpace);
 				return Status;
 			}
 
@@ -437,12 +463,21 @@
 		/*
 		 * Relock the address space and segment
 		 */
-		MmLockAddressSpace(AddressSpace);
+		if (!Locked)
+			MmLockAddressSpace(AddressSpace);
 
 		/*
 		 * Mark the offset within the section as having valid, in-memory
 		 * data
 		 */
+		MmLockSectionSegment(Segment);
+		if (Entry != MiGetPageEntrySectionSegment(Segment, &Offset))
+		{
+			// Handled elsewhere
+			MmUnlockSectionSegment(Segment);
+			return STATUS_SUCCESS;
+		}
+
 		Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
 		MiSetPageEntrySectionSegment(Segment, &Offset, Entry);
 
@@ -497,6 +532,8 @@
 		//DPRINT("Address 0x%.8X\n", Address);
 		return(STATUS_SUCCESS);
 	}
+
+	ASSERT(FALSE);
 }
 
 NTSTATUS
@@ -1400,7 +1437,7 @@
    /* And finish their initialization */
    for ( i = 0; i < ImageSectionObject->NrSegments; ++ i )
    {
-      ExInitializeFastMutex(&ImageSectionObject->Segments[i].Lock);
+      KeInitializeGuardedMutex(&ImageSectionObject->Segments[i].Lock);
 	  ImageSectionObject->Segments[i].Flags = MM_IMAGE_SEGMENT;
       ImageSectionObject->Segments[i].ReferenceCount = 1;
 	  MiInitializeSectionPageTable(&ImageSectionObject->Segments[i]);

Modified: branches/arty-newcc/ntoskrnl/mm/section/io.c
URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/section/io.c?rev=44290&r1=44289&r2=44290&view=diff
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/section/io.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/section/io.c [iso-8859-1] Thu Nov 26 23:50:50 2009
@@ -54,8 +54,6 @@
 #pragma alloc_text(INIT, MmInitSectionImplementation)
 #endif
 
-KEVENT CcpLazyWriteEvent;
-
 /*
  * FUNCTION:  Waits in kernel mode indefinitely for a file object lock.
  * ARGUMENTS: PFILE_OBJECT to wait for.
@@ -428,82 +426,65 @@
  ULONG Length,
  PFN_TYPE Page)
 {
+	PFN_TYPE XPage;
 	NTSTATUS Status;
-	PVOID Hyperspace;
 	IO_STATUS_BLOCK Iosb;
-	KIRQL OldIrql;
-	PVOID PageBuffer = ExAllocatePool(NonPagedPool, PAGE_SIZE);
-
-	if (!PageBuffer) return STATUS_NO_MEMORY;
-
-	OldIrql = KfRaiseIrql(DISPATCH_LEVEL);
-	Hyperspace = MmCreateHyperspaceMapping(Page);
-	RtlCopyMemory(PageBuffer, Hyperspace, PAGE_SIZE);
-	MmDeleteHyperspaceMapping(Hyperspace);
-	KfLowerIrql(OldIrql);
+	PVOID PageBuf = 0;
+	PMEMORY_AREA TmpArea;
+	PHYSICAL_ADDRESS BoundaryAddressMultiple;
+
+	BoundaryAddressMultiple.QuadPart = 0;
+
+	MmLockAddressSpace(MmGetKernelAddressSpace());
+
+	Status = MmCreateMemoryArea
+		(MmGetKernelAddressSpace(),
+		 MEMORY_AREA_VIRTUAL_MEMORY, 
+		 &PageBuf,
+		 PAGE_SIZE,
+		 PAGE_READWRITE,
+		 &TmpArea,
+		 FALSE,
+		 MEM_TOP_DOWN,
+		 BoundaryAddressMultiple);
+
+	if (!NT_SUCCESS(Status))
+	{
+		DPRINT1("STATUS_NO_MEMORY: %x\n", Status);
+		MmUnlockAddressSpace(MmGetKernelAddressSpace());
+		return STATUS_NO_MEMORY;
+	}
+	
+	Status = MmCreateVirtualMapping(NULL, PageBuf, PAGE_READWRITE, &Page, 1);
+	if (!NT_SUCCESS(Status))
+	{
+		MmFreeMemoryArea(MmGetKernelAddressSpace(), TmpArea, NULL, NULL);
+		MmUnlockAddressSpace(MmGetKernelAddressSpace());
+		DPRINT1("Status: %x\n", Status);
+		return Status;
+	}
+	MmReferencePage(Page);
+	MmUnlockAddressSpace(MmGetKernelAddressSpace());
 
 	DPRINT("MiWriteBackPage(%wZ,%08x%08x)\n", &FileObject->FileName, FileOffset->u.HighPart, FileOffset->u.LowPart);
 	Status = MiSimpleWrite
 		(FileObject,
 		 FileOffset,
-		 PageBuffer,
+		 PageBuf,
 		 Length,
 		 &Iosb);
 
-	ExFreePool(PageBuffer);
-	
 	if (!NT_SUCCESS(Status))
 	{
 		DPRINT1("MiSimpleWrite failed (%x)\n", Status);
 	}
 
+	MmLockAddressSpace(MmGetKernelAddressSpace());
+	MmDeleteVirtualMapping(NULL, PageBuf, FALSE, NULL, &XPage);
+	ASSERT(XPage == Page);
+	MmFreeMemoryArea(MmGetKernelAddressSpace(), TmpArea, NULL, NULL);
+	MmDereferencePage(Page);
+	MmUnlockAddressSpace(MmGetKernelAddressSpace());
+
 	return Status;
 }
-
-VOID
-NTAPI
-MiWriteThread()
-{
-	BOOLEAN Complete;
-	NTSTATUS Status;
-	LIST_ENTRY OldHead;
-	PLIST_ENTRY Entry;
-	PWRITE_SCHEDULE_ENTRY WriteEntry;
-
-	ExAcquireFastMutex(&MiWriteMutex);
-	Complete = IsListEmpty(&MiWriteScheduleListHead);
-	ExReleaseFastMutex(&MiWriteMutex);
-	if (Complete)
-	{
-		DPRINT1("No items await writing\n");
-		KeSetEvent(&CcpLazyWriteEvent, IO_NO_INCREMENT, FALSE);
-	}
-	
-	DPRINT1("Lazy write items are available\n");
-	KeResetEvent(&CcpLazyWriteEvent);
-	
-	ExAcquireFastMutex(&MiWriteMutex);
-	RtlCopyMemory(&OldHead, &MiWriteScheduleListHead, sizeof(OldHead));
-	OldHead.Flink->Blink = &OldHead;
-	OldHead.Blink->Flink = &OldHead;
-	InitializeListHead(&MiWriteScheduleListHead);
-	ExReleaseFastMutex(&MiWriteMutex);
-	
-	for (Entry = OldHead.Flink;
-		 !IsListEmpty(&OldHead);
-		 Entry = OldHead.Flink)
-	{
-		WriteEntry = CONTAINING_RECORD(Entry, WRITE_SCHEDULE_ENTRY, Entry);
-		Status = MiWriteBackPage(WriteEntry->FileObject, &WriteEntry->FileOffset, WriteEntry->Length, WriteEntry->Page);
-
-		if (!NT_SUCCESS(Status))
-		{
-			DPRINT1("MiSimpleWrite failed (%x)\n", Status);
-		}
-
-		MmDereferencePage(WriteEntry->Page);
-		ObDereferenceObject(WriteEntry->FileObject);
-		RemoveEntryList(&WriteEntry->Entry);
-		ExFreePool(WriteEntry);
-	}
-}

Modified: branches/arty-newcc/ntoskrnl/mm/section/pagefile.c
URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/section/pagefile.c?rev=44290&r1=44289&r2=44290&view=diff
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/section/pagefile.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/section/pagefile.c [iso-8859-1] Thu Nov 26 23:50:50 2009
@@ -123,13 +123,15 @@
 
 	if (Entry == 0)
 	{
-		MmUnlockAddressSpace(AddressSpace);
+		MmUnlockSectionSegment(Segment);
+		if (!Locked)
+			MmUnlockAddressSpace(AddressSpace);
 		Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page);
 		if (!NT_SUCCESS(Status))
 		{
 			DPRINT1("MmRequestPageMemoryConsumer failed (Status %x)\n", Status);
-			MmLockAddressSpace(AddressSpace);
-			MmUnlockSectionSegment(Segment);
+			if (!Locked)
+				MmLockAddressSpace(AddressSpace);
 			return Status;
 		}
 
@@ -144,16 +146,24 @@
 			DPRINT1("Unable to create virtual mapping\n");
 			MmReleasePageMemoryConsumer(MC_USER, Page);
 			DPRINT("Release page %x\n", Page);
-			MmLockAddressSpace(AddressSpace);
-			MmUnlockSectionSegment(Segment);
+			if (!Locked)
+				MmLockAddressSpace(AddressSpace);
 			return Status;
 		}
 
 		/*
 		 * Relock the address space and segment
 		 */
-		MmLockAddressSpace(AddressSpace);
-
+		if (!Locked)
+			MmLockAddressSpace(AddressSpace);
+
+		MmLockSectionSegment(Segment);
+		if (Entry != MiGetPageEntrySectionSegment(Segment, &Offset))
+		{
+			// Already handled
+			MmUnlockSectionSegment(Segment);
+			return STATUS_SUCCESS;
+		}
 		/*
 		 * Mark the offset within the section as having valid, in-memory
 		 * data
@@ -282,7 +292,7 @@
    }
    Section->Segment = Segment;
    Segment->ReferenceCount = 1;
-   ExInitializeFastMutex(&Segment->Lock);
+   KeInitializeGuardedMutex(&Segment->Lock);
    Segment->Protection = SectionPageProtection;
    Segment->RawLength.QuadPart = MaximumSize.QuadPart;
    Segment->Length.QuadPart = PAGE_ROUND_UP(MaximumSize.QuadPart);
@@ -418,8 +428,6 @@
          ASSERT(FALSE);
       }
       MmReleasePageMemoryConsumer(MC_USER, Page);
-      PageOp->Status = STATUS_SUCCESS;
-      MmspCompleteAndReleasePageOp(PageOp);
       return(STATUS_SUCCESS);
    }
    else if (!Context.WasDirty && Context.Private && SwapEntry != 0)
@@ -435,8 +443,6 @@
          ASSERT(FALSE);
       }
       MmReleasePageMemoryConsumer(MC_USER, Page);
-      PageOp->Status = STATUS_SUCCESS;
-      MmspCompleteAndReleasePageOp(PageOp);
       return(STATUS_SUCCESS);
    }
 
@@ -485,8 +491,6 @@
             MiSetPageEntrySectionSegment(Context.Segment, &Context.Offset, Entry);
          }
          MmUnlockAddressSpace(AddressSpace);
-         PageOp->Status = STATUS_UNSUCCESSFUL;
-         MmspCompleteAndReleasePageOp(PageOp);
          return(STATUS_PAGEFILE_QUOTA);
       }
    }
@@ -531,8 +535,6 @@
          MiSetPageEntrySectionSegment(Context.Segment, &Context.Offset, Entry);
       }
       MmUnlockAddressSpace(AddressSpace);
-      PageOp->Status = STATUS_UNSUCCESSFUL;
-      MmspCompleteAndReleasePageOp(PageOp);
       return(STATUS_UNSUCCESSFUL);
    }
 
@@ -561,8 +563,6 @@
       MiSetPageEntrySectionSegment(Context.Segment, &Context.Offset, Entry);
    }
 
-   PageOp->Status = STATUS_SUCCESS;
-   MmspCompleteAndReleasePageOp(PageOp);
    return(STATUS_SUCCESS);
 }
 




More information about the Ros-diffs mailing list