Author: arty
Date: Tue Jan  5 16:15:30 2010
New Revision: 44944

URL: http://svn.reactos.org/svn/reactos?rev=44944&view=rev
Log:
Fix failure case for pageout (including pulling a page that's being swapped 
out),
Reorder operations on not present to handle wait entries properly.
Fix some balancer issues and initialize rmap earlier, as there's no reason to 
wait.

Removed:
    branches/arty-newcc/ntoskrnl/mm/pageop.c
Modified:
    branches/arty-newcc/ntoskrnl/mm/anonmem.c
    branches/arty-newcc/ntoskrnl/mm/balance.c
    branches/arty-newcc/ntoskrnl/mm/elf.inc.h
    branches/arty-newcc/ntoskrnl/mm/elf32.c
    branches/arty-newcc/ntoskrnl/mm/mmfault.c
    branches/arty-newcc/ntoskrnl/mm/mminit.c
    branches/arty-newcc/ntoskrnl/mm/rmap.c
    branches/arty-newcc/ntoskrnl/mm/section/fault.c
    branches/arty-newcc/ntoskrnl/mm/section/pagefile.c

Modified: branches/arty-newcc/ntoskrnl/mm/anonmem.c
URL: 
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/anonmem.c?rev=44944&r1=44943&r2=44944&view=diff
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/anonmem.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/anonmem.c [iso-8859-1] Tue Jan  5 16:15:30 
2010
@@ -790,49 +790,12 @@
 {
    PLIST_ENTRY current_entry;
    PMM_REGION current;
-   ULONG i;
 
    DPRINT("MmFreeVirtualMemory(Process %p  MemoryArea %p)\n", Process,
           MemoryArea);
 
    /* Mark this memory area as about to be deleted. */
    MemoryArea->DeleteInProgress = TRUE;
-
-   /*
-    * Wait for any ongoing paging operations. Notice that since we have
-    * flagged this memory area as deleted no more page ops will be added.
-    */
-   if (MemoryArea->PageOpCount > 0)
-   {
-      ULONG_PTR MemoryAreaLength = (ULONG_PTR)MemoryArea->EndingAddress -
-                                   (ULONG_PTR)MemoryArea->StartingAddress;
-      const ULONG nPages = PAGE_ROUND_UP(MemoryAreaLength) >> PAGE_SHIFT;
-
-      for (i = 0; i < nPages && MemoryArea->PageOpCount != 0; ++i)
-      {
-         PMM_PAGEOP PageOp;
-         PageOp = MmCheckForPageOp(MemoryArea, Process->UniqueProcessId,
-                                   
(PVOID)((ULONG_PTR)MemoryArea->StartingAddress + (i * PAGE_SIZE)),
-                                   NULL, 0);
-         if (PageOp != NULL)
-         {
-            NTSTATUS Status;
-            MmUnlockAddressSpace(&Process->Vm);
-            Status = KeWaitForSingleObject(&PageOp->CompletionEvent,
-                                           0,
-                                           KernelMode,
-                                           FALSE,
-                                           NULL);
-            if (Status != STATUS_SUCCESS)
-            {
-               DPRINT1("Failed to wait for page op\n");
-               KeBugCheck(MEMORY_MANAGEMENT);
-            }
-            MmLockAddressSpace(&Process->Vm);
-            MmReleasePageOp(PageOp);
-         }
-      }
-   }
 
    /* Free all the individual segments. */
    current_entry = MemoryArea->Data.VirtualMemoryData.RegionListHead.Flink;

Modified: branches/arty-newcc/ntoskrnl/mm/balance.c
URL: 
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/balance.c?rev=44944&r1=44943&r2=44944&view=diff
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/balance.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/balance.c [iso-8859-1] Tue Jan  5 16:15:30 
2010
@@ -31,6 +31,7 @@
 
 /* GLOBALS ******************************************************************/
 
+BOOLEAN MiBalancerInitialized = FALSE;
 MM_MEMORY_CONSUMER MiMemoryConsumers[MC_MAXIMUM];
 /*static*/ ULONG MiMinimumAvailablePages = 128;
 static ULONG MiNrTotalPages;
@@ -170,8 +171,9 @@
 MiIsBalancerThread(VOID)
 {
    return 
-          PsGetCurrentThread()->Cid.UniqueThread == 
-          MiBalancerThreadId.UniqueThread;
+          !MiBalancerInitialized ||
+          (PsGetCurrentThread()->Cid.UniqueThread == 
+               MiBalancerThreadId.UniqueThread);
 }
 
 /*
@@ -284,6 +286,8 @@
 
    WaitObjects[0] = &MiBalancerEvent;
    WaitObjects[1] = &MiBalancerTimer;
+
+   MiBalancerInitialized = TRUE;
 
    while (1)
    {
@@ -335,23 +339,14 @@
 {
    KPRIORITY Priority;
    NTSTATUS Status;
-#if !defined(__GNUC__)
-
-   LARGE_INTEGER dummyJunkNeeded;
-   dummyJunkNeeded.QuadPart = -20000000; /* 2 sec */
-   ;
-#endif
-
+   LARGE_INTEGER BalancerInterval;
+   BalancerInterval.QuadPart = -20000000; /* 2 sec */
 
    KeInitializeEvent(&MiBalancerEvent, SynchronizationEvent, FALSE);
    KeInitializeEvent(&MiBalancerContinue, SynchronizationEvent, FALSE);
    KeInitializeTimerEx(&MiBalancerTimer, SynchronizationTimer);
    KeSetTimerEx(&MiBalancerTimer,
-#if defined(__GNUC__)
-                (LARGE_INTEGER)(LONGLONG)-20000000LL,     /* 2 sec */
-#else
-                dummyJunkNeeded,
-#endif
+                BalancerInterval,
                 2000,         /* 2 sec */
                 NULL);
 

Modified: branches/arty-newcc/ntoskrnl/mm/elf.inc.h
URL: 
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/elf.inc.h?rev=44944&r1=44943&r2=44944&view=diff
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/elf.inc.h [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/elf.inc.h [iso-8859-1] Tue Jan  5 16:15:30 
2010
@@ -8,8 +8,6 @@
 #endif
 
 #include <elf/elf.h>
-
-#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3
 
 /* TODO: Intsafe should be made into a library, as it's generally useful */
 static __inline BOOLEAN Intsafe_CanAddULongPtr

Modified: branches/arty-newcc/ntoskrnl/mm/elf32.c
URL: 
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/elf32.c?rev=44944&r1=44943&r2=44944&view=diff
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/elf32.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/elf32.c [iso-8859-1] Tue Jan  5 16:15:30 
2010
@@ -9,8 +9,6 @@
 #include <ntoskrnl.h>
 #define __ELF_WORD_SIZE 32
 #include "elf.inc.h"
-
-#define IMAGE_FILE_MACHINE_UNKNOWN 0
 
 extern NTSTATUS NTAPI Elf64FmtCreateSection
 (

Modified: branches/arty-newcc/ntoskrnl/mm/mmfault.c
URL: 
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/mmfault.c?rev=44944&r1=44943&r2=44944&view=diff
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/mmfault.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/mmfault.c [iso-8859-1] Tue Jan  5 16:15:30 
2010
@@ -161,6 +161,7 @@
          if (Status == STATUS_SUCCESS + 1)
          {
                  // Wait page ...
+                 DPRINT1("Waiting for %x\n", Address);
                  if (!NT_SUCCESS
                          (KeWaitForSingleObject
                           (&MmWaitPageEvent,
@@ -169,6 +170,7 @@
                                FALSE,
                                NULL)))
                          ASSERT(FALSE);
+                 DPRINT1("Restarting fault %x\n", Address);
                  Status = STATUS_MM_RESTART_OPERATION;
          }
          else if (Status == STATUS_MORE_PROCESSING_REQUIRED)
@@ -341,6 +343,7 @@
                if (Status == STATUS_SUCCESS + 1)
                {
                        // Wait page ...
+                       DPRINT1("Waiting for %x\n", Address);
                        if (!NT_SUCCESS
                                (KeWaitForSingleObject
                                 (&MmWaitPageEvent,
@@ -349,6 +352,7 @@
                                  FALSE,
                                  NULL)))
                                ASSERT(FALSE);
+                       DPRINT1("Done waiting for %x\n", Address);
                        Status = STATUS_MM_RESTART_OPERATION;
                }
                else if (Status == STATUS_MORE_PROCESSING_REQUIRED)

Modified: branches/arty-newcc/ntoskrnl/mm/mminit.c
URL: 
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/mminit.c?rev=44944&r1=44943&r2=44944&view=diff
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/mminit.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/mminit.c [iso-8859-1] Tue Jan  5 16:15:30 
2010
@@ -467,7 +467,10 @@
         
         /* Dump the address space */
         MiDbgDumpAddressSpace();
-        
+
+               /* Initialize rmap implementation */
+        MmInitializeRmapList();
+
         /* Initialize paged pool */
         MmInitializePagedPool();
         
@@ -496,8 +499,6 @@
     }
     else if (Phase == 1)
     {
-        MmInitializeRmapList();
-        MmInitializePageOp();
         MmInitSectionImplementation();
         MmInitPagingFile();
         

Removed: branches/arty-newcc/ntoskrnl/mm/pageop.c
URL: 
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/pageop.c?rev=44943&view=auto
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/pageop.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/pageop.c (removed)
@@ -1,268 +1,0 @@
-/*
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/mm/pageop.c
- * PURPOSE:         No purpose listed.
- *
- * PROGRAMMERS:     David Welch ([email protected])
- */
-
-/* INCLUDES ****************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <debug.h>
-
-#if defined (ALLOC_PRAGMA)
-#pragma alloc_text(INIT, MmInitializePageOp)
-#endif
-
-
-/* GLOBALS *******************************************************************/
-
-#define PAGEOP_HASH_TABLE_SIZE       (32)
-
-static KSPIN_LOCK MmPageOpHashTableLock;
-static PMM_PAGEOP MmPageOpHashTable[PAGEOP_HASH_TABLE_SIZE];
-static NPAGED_LOOKASIDE_LIST MmPageOpLookasideList;
-
-/* FUNCTIONS *****************************************************************/
-
-VOID
-NTAPI
-MmReleasePageOp(PMM_PAGEOP PageOp)
-/*
- * FUNCTION: Release a reference to a page operation descriptor
- */
-{
-   KIRQL oldIrql;
-   PMM_PAGEOP PrevPageOp;
-
-   KeAcquireSpinLock(&MmPageOpHashTableLock, &oldIrql);
-   PageOp->ReferenceCount--;
-   if (PageOp->ReferenceCount > 0)
-   {
-      KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
-      return;
-   }
-   (void)InterlockedDecrementUL(&PageOp->MArea->PageOpCount);
-   PrevPageOp = MmPageOpHashTable[PageOp->Hash];
-   if (PrevPageOp == PageOp)
-   {
-      MmPageOpHashTable[PageOp->Hash] = PageOp->Next;
-      KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
-      ExFreeToNPagedLookasideList(&MmPageOpLookasideList, PageOp);
-      return;
-   }
-   while (PrevPageOp->Next != NULL)
-   {
-      if (PrevPageOp->Next == PageOp)
-      {
-         PrevPageOp->Next = PageOp->Next;
-         KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
-         ExFreeToNPagedLookasideList(&MmPageOpLookasideList, PageOp);
-         return;
-      }
-      PrevPageOp = PrevPageOp->Next;
-   }
-   KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
-   KeBugCheck(MEMORY_MANAGEMENT);
-}
-
-PMM_PAGEOP
-NTAPI
-MmCheckForPageOp(PMEMORY_AREA MArea, HANDLE Pid, PVOID Address,
-                 PMM_SECTION_SEGMENT Segment, ULONG Offset)
-{
-   ULONG_PTR Hash;
-   KIRQL oldIrql;
-   PMM_PAGEOP PageOp;
-
-   /*
-    * Calcuate the hash value for pageop structure
-    */
-   if (MArea->Type == MEMORY_AREA_SECTION_VIEW)
-   {
-      Hash = (((ULONG_PTR)Segment) | (((ULONG_PTR)Offset) / PAGE_SIZE));
-   }
-   else
-   {
-      Hash = (((ULONG_PTR)Pid) | (((ULONG_PTR)Address) / PAGE_SIZE));
-   }
-   Hash = Hash % PAGEOP_HASH_TABLE_SIZE;
-
-   KeAcquireSpinLock(&MmPageOpHashTableLock, &oldIrql);
-
-   /*
-    * Check for an existing pageop structure
-    */
-   PageOp = MmPageOpHashTable[Hash];
-   while (PageOp != NULL)
-   {
-      if (MArea->Type == MEMORY_AREA_SECTION_VIEW)
-      {
-         if (PageOp->Segment == Segment &&
-               PageOp->Offset == Offset)
-         {
-            break;
-         }
-      }
-      else
-      {
-         if (PageOp->Pid == Pid &&
-               PageOp->Address == Address)
-         {
-            break;
-         }
-      }
-      PageOp = PageOp->Next;
-   }
-
-   /*
-    * If we found an existing pageop then increment the reference count
-    * and return it.
-    */
-   if (PageOp != NULL)
-   {
-      PageOp->ReferenceCount++;
-      KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
-      return(PageOp);
-   }
-   KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
-   return(NULL);
-}
-
-PMM_PAGEOP
-NTAPI
-MmGetPageOp(PMEMORY_AREA MArea, HANDLE Pid, PVOID Address,
-            PMM_SECTION_SEGMENT Segment, ULONG Offset, ULONG OpType, BOOLEAN 
First)
-/*
- * FUNCTION: Get a page operation descriptor corresponding to
- * the memory area and either the segment, offset pair or the
- * pid, address pair.
- */
-{
-   ULONG_PTR Hash;
-   KIRQL oldIrql;
-   PMM_PAGEOP PageOp;
-
-   /*
-    * Calcuate the hash value for pageop structure
-    */
-   if (MArea->Type == MEMORY_AREA_SECTION_VIEW)
-   {
-      Hash = (((ULONG_PTR)Segment) | (((ULONG_PTR)Offset) / PAGE_SIZE));
-   }
-   else
-   {
-      Hash = (((ULONG_PTR)Pid) | (((ULONG_PTR)Address) / PAGE_SIZE));
-   }
-   Hash = Hash % PAGEOP_HASH_TABLE_SIZE;
-
-   KeAcquireSpinLock(&MmPageOpHashTableLock, &oldIrql);
-
-   /*
-    * Check for an existing pageop structure
-    */
-   PageOp = MmPageOpHashTable[Hash];
-   while (PageOp != NULL)
-   {
-      if (MArea->Type == MEMORY_AREA_SECTION_VIEW)
-      {
-         if (PageOp->Segment == Segment &&
-               PageOp->Offset == Offset)
-         {
-            break;
-         }
-      }
-      else
-      {
-         if (PageOp->Pid == Pid &&
-               PageOp->Address == Address)
-         {
-            break;
-         }
-      }
-      PageOp = PageOp->Next;
-   }
-
-   /*
-    * If we found an existing pageop then increment the reference count
-    * and return it.
-    */
-   if (PageOp != NULL)
-   {
-      if (First)
-      {
-         PageOp = NULL;
-      }
-      else
-      {
-         PageOp->ReferenceCount++;
-      }
-      KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
-      return(PageOp);
-   }
-
-   /*
-    * Otherwise add a new pageop.
-    */
-   PageOp = ExAllocateFromNPagedLookasideList(&MmPageOpLookasideList);
-   if (PageOp == NULL)
-   {
-      KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
-      KeBugCheck(MEMORY_MANAGEMENT);
-      return(NULL);
-   }
-
-   if (MArea->Type != MEMORY_AREA_SECTION_VIEW)
-   {
-      PageOp->Pid = Pid;
-      PageOp->Address = Address;
-   }
-   else
-   {
-      PageOp->Segment = Segment;
-      PageOp->Offset = Offset;
-   }
-   PageOp->ReferenceCount = 1;
-   PageOp->Next = MmPageOpHashTable[Hash];
-   PageOp->Hash = Hash;
-   PageOp->Thread = PsGetCurrentThread();
-   PageOp->Abandoned = FALSE;
-   PageOp->Status = STATUS_PENDING;
-   PageOp->OpType = OpType;
-   PageOp->MArea = MArea;
-   KeInitializeEvent(&PageOp->CompletionEvent, NotificationEvent, FALSE);
-   MmPageOpHashTable[Hash] = PageOp;
-   (void)InterlockedIncrementUL(&MArea->PageOpCount);
-
-   KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
-   return(PageOp);
-}
-
-VOID
-INIT_FUNCTION
-NTAPI
-MmInitializePageOp(VOID)
-{
-   memset(MmPageOpHashTable, 0, sizeof(MmPageOpHashTable));
-   KeInitializeSpinLock(&MmPageOpHashTableLock);
-
-   ExInitializeNPagedLookasideList (&MmPageOpLookasideList,
-                                    NULL,
-                                    NULL,
-                                    0,
-                                    sizeof(MM_PAGEOP),
-                                    TAG_MM_PAGEOP,
-                                    50);
-}
-
-
-
-
-
-
-
-
-

Modified: branches/arty-newcc/ntoskrnl/mm/rmap.c
URL: 
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/rmap.c?rev=44944&r1=44943&r2=44944&view=diff
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/rmap.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/rmap.c [iso-8859-1] Tue Jan  5 16:15:30 2010
@@ -342,19 +342,30 @@
    {
           DPRINT("About to finalize section page %x %s\n", Page, Dirty ? 
"dirty" : "clean");
 
-          Evicted = 
-                  NT_SUCCESS(Status) &&
-                  NT_SUCCESS(MmFinalizeSectionPageOut(Segment, &FileOffset, 
Page, Dirty));
-
-          if (!Evicted && SectionPage)
-          {
-                  DPRINT
-                          ("Failed to page out, replacing %x at %x in segment 
%x\n",
-                               SectionPage, FileOffset.LowPart, Segment);
+          if (MmGetRmapListHeadPage(Page))
+          {
+                  DPRINT1("Page %x was re-acquired while we were evicting 
it\n", Page);
                   MmLockSectionSegment(Segment);
                   MiSetPageEntrySectionSegment(Segment, &FileOffset, Dirty ? 
DIRTY_SSE(MAKE_PFN_SSE(SectionPage)) : MAKE_PFN_SSE(SectionPage));
                   MmUnlockSectionSegment(Segment);
                   KeSetEvent(&MmWaitPageEvent, IO_NO_INCREMENT, FALSE);
+          }
+          else
+          {
+                  Evicted = 
+                          NT_SUCCESS(Status) &&
+                          NT_SUCCESS(MmFinalizeSectionPageOut(Segment, 
&FileOffset, Page, Dirty));
+                  
+                  if (!Evicted && SectionPage)
+                  {
+                          DPRINT1
+                                  ("Failed to page out, replacing %x at %x in 
segment %x\n",
+                                       SectionPage, FileOffset.LowPart, 
Segment);
+                          MmLockSectionSegment(Segment);
+                          MiSetPageEntrySectionSegment(Segment, &FileOffset, 
Dirty ? DIRTY_SSE(MAKE_PFN_SSE(SectionPage)) : MAKE_PFN_SSE(SectionPage));
+                          MmUnlockSectionSegment(Segment);
+                          KeSetEvent(&MmWaitPageEvent, IO_NO_INCREMENT, FALSE);
+                  }
           }
    }
 

Modified: branches/arty-newcc/ntoskrnl/mm/section/fault.c
URL: 
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/section/fault.c?rev=44944&r1=44943&r2=44944&view=diff
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/section/fault.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/section/fault.c [iso-8859-1] Tue Jan  5 
16:15:30 2010
@@ -71,7 +71,7 @@
        PMM_REGION Region;
        PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
 
-       DPRINT1("Not Present: %p %p (%p-%p)\n", AddressSpace, Address, 
MemoryArea->StartingAddress, MemoryArea->EndingAddress);
+       DPRINT("Not Present: %p %p (%p-%p)\n", AddressSpace, Address, 
MemoryArea->StartingAddress, MemoryArea->EndingAddress);
     
        /*
         * There is a window between taking the page fault and locking the
@@ -115,6 +115,7 @@
        {
                DPRINT("FileName %wZ\n", &Segment->FileObject->FileName);
        }
+
        DPRINT("Total Offset %08x%08x\n", TotalOffset.HighPart, 
TotalOffset.LowPart);
 
        /*
@@ -151,8 +152,73 @@
                DPRINT("Normal %x\n", Attributes);
        }
 
-grab_page:
-       if (Entry && !IS_SWAP_FROM_SSE(Entry))
+       if (Required->State && Required->Page[0])
+       {
+               DPRINT("Have file and page, set page in section @ %x\n", 
TotalOffset.LowPart);
+               Status = MiSetPageEntrySectionSegment
+                       (Segment, &TotalOffset, Entry = 
MAKE_PFN_SSE(Required->Page[0]));
+               if (NT_SUCCESS(Status))
+               {
+                       MmReferencePage(Required->Page[0]);
+                       Status = MmCreateVirtualMapping(Process, Address, 
Attributes, Required->Page, 1);
+                       if (NT_SUCCESS(Status))
+                       {
+                               MmInsertRmap(Required->Page[0], Process, 
Address);
+                       }
+                       else
+                       {
+                               MmDereferencePage(Required->Page[0]);
+                       }
+               }
+               MmUnlockSectionSegment(Segment);
+               DPRINT("XXX Set Event %x\n", Status);
+               KeSetEvent(&MmWaitPageEvent, IO_NO_INCREMENT, FALSE);
+               DPRINT1("Status %x\n", Status);
+               return Status;
+       }
+       else if (MmIsPageSwapEntry(Process, Address))
+       {
+               SWAPENTRY SwapEntry;
+               MmGetPageFileMapping(Process, Address, &SwapEntry);
+               if (SwapEntry == MM_WAIT_ENTRY)
+               {
+                       DPRINT1("Wait for page entry in section\n");
+                       return STATUS_SUCCESS + 1;
+               }
+               else
+               {
+                       DPRINT("Swap in\n");
+                       MmCreatePageFileMapping(Process, Address, 
MM_WAIT_ENTRY);
+                       Required->State = 7;
+                       Required->Consumer = Consumer;
+                       Required->SwapEntry = SwapEntry;
+                       Required->DoAcquisition = MiSwapInPage;
+                       MmUnlockSectionSegment(Segment);
+                       return STATUS_MORE_PROCESSING_REQUIRED;
+               }
+       }
+       else if (IS_SWAP_FROM_SSE(Entry))
+       {
+               SWAPENTRY SwapEntry = SWAPENTRY_FROM_SSE(Entry);
+               if (SwapEntry == MM_WAIT_ENTRY)
+               {
+                       DPRINT1("Wait for page entry in section\n");
+                       return STATUS_SUCCESS + 1;
+               }
+               else
+               {
+                       DPRINT("Swap in\n");
+                       MmCreatePageFileMapping(Process, Address, 
MM_WAIT_ENTRY);
+                       MiSetPageEntrySectionSegment(Segment, &TotalOffset, 
MAKE_SWAP_SSE(MM_WAIT_ENTRY));
+                       Required->State = 7;
+                       Required->Consumer = Consumer;
+                       Required->SwapEntry = SwapEntry;
+                       Required->DoAcquisition = MiSwapInPage;
+                       MmUnlockSectionSegment(Segment);
+                       return STATUS_MORE_PROCESSING_REQUIRED;
+               }
+       }
+       else if (Entry && !IS_SWAP_FROM_SSE(Entry))
        {
                PFN_TYPE Page = PFN_FROM_SSE(Entry);
                DPRINT("Page %x\n", Page);
@@ -166,23 +232,10 @@
                DPRINT("XXX Set Event %x\n", Status);
                KeSetEvent(&MmWaitPageEvent, IO_NO_INCREMENT, FALSE);
                MmUnlockSectionSegment(Segment);
+               DPRINT1("Status %x\n", Status);
                return Status;
        }
-
-       if (Required->State && Required->Page[0])
-       {
-               DPRINT("Have file and page, set page in section @ %x\n", 
TotalOffset.LowPart);
-               Status = MiSetPageEntrySectionSegment
-                       (Segment, &TotalOffset, Entry = 
MAKE_PFN_SSE(Required->Page[0]));
-               if (NT_SUCCESS(Status))
-               {
-                       goto grab_page;
-               }
-               MmUnlockSectionSegment(Segment);
-               return Status;
-       }
-
-       if (Entry == 0)
+       else
        {
                DPRINT("Get page into section\n");
                /*
@@ -213,17 +266,6 @@
                        MmUnlockSectionSegment(Segment);
                        return STATUS_MORE_PROCESSING_REQUIRED;
                }
-       }
-       else
-       {
-               DPRINT("Swap in\n");
-               Required->State = 7;
-               Required->Consumer = Consumer;
-               Required->SwapEntry = SWAPENTRY_FROM_SSE(Entry);
-               MiSetPageEntrySectionSegment(Segment, &TotalOffset, 
MAKE_SWAP_SSE(MM_WAIT_ENTRY));
-               Required->DoAcquisition = MiSwapInPage;
-               MmUnlockSectionSegment(Segment);
-               return STATUS_MORE_PROCESSING_REQUIRED;
        }
 }
 
@@ -311,6 +353,7 @@
                        DPRINT("Set in section @ %x\n", Offset.LowPart);
                        Status = MiSetPageEntrySectionSegment
                                (Segment, &Offset, MAKE_PFN_SSE(Page));
+                       KeSetEvent(&MmWaitPageEvent, IO_NO_INCREMENT, FALSE);
                }
 
                if (Required->State & 2)
@@ -330,6 +373,7 @@
                if (Required->State & 4)
                {
                        DPRINT("Take a reference\n");
+                       Status = STATUS_SUCCESS;
                        MmReferencePage(Page);
                }
 
@@ -349,8 +393,7 @@
                MmUnlockSectionSegment(Segment);
                return STATUS_MORE_PROCESSING_REQUIRED;
        }
-
-       if (HasSwapEntry)
+       else if (HasSwapEntry)
        {
                MmGetPageFileMapping(Process, (PVOID)PAddress, 
&Required->SwapEntry);
                if (Required->SwapEntry == MM_WAIT_ENTRY)
@@ -363,28 +406,18 @@
                 * Must be private page we have swapped out.
                 */
                DPRINT("Private swapped out page\n");
+               MmCreatePageFileMapping(Process, Address, MM_WAIT_ENTRY);
                Required->State = 2;
                Required->Consumer = MC_USER;
-               MmCreatePageFileMapping(Process, Address, MM_WAIT_ENTRY);
                Required->DoAcquisition = MiSwapInPage;
                MmUnlockSectionSegment(Segment);
                return STATUS_MORE_PROCESSING_REQUIRED;
        }
-
-       /*
-        * Map anonymous memory for BSS sections
-        */
-       if (Entry == 0 || 
-               (Segment->Image.Characteristics & 
IMAGE_SCN_CNT_UNINITIALIZED_DATA) ||
-               Offset.QuadPart >= PAGE_ROUND_UP(Segment->RawLength.QuadPart)) 
-       {
-               DPRINT("BSS Page\n");
-               Required->State = 2;
-               Required->Amount = 1;
-               Required->Consumer = MC_USER;
-               Required->DoAcquisition = MiGetOnePage;
-               MmUnlockSectionSegment(Segment);
-               return STATUS_MORE_PROCESSING_REQUIRED;
+       else if (IS_SWAP_FROM_SSE(Entry) && SWAPENTRY_FROM_SSE(Entry) == 
MM_WAIT_ENTRY)
+       {
+               DPRINT("Waiting\n");
+               MmUnlockSectionSegment(Segment);
+               return STATUS_SUCCESS + 1;
        }
        else if (IS_SWAP_FROM_SSE(Entry))
        {
@@ -394,6 +427,21 @@
                MmGetPageFileMapping(Process, (PVOID)PAddress, 
&Required->SwapEntry);
                MmCreatePageFileMapping(Process, Address, MM_WAIT_ENTRY);
                Required->DoAcquisition = MiSwapInPage;
+               MmUnlockSectionSegment(Segment);
+               return STATUS_MORE_PROCESSING_REQUIRED;
+       }
+       /*
+        * Map anonymous memory for BSS sections
+        */
+       else if (Entry == 0 &&
+                        ((Segment->Image.Characteristics & 
IMAGE_SCN_CNT_UNINITIALIZED_DATA) ||
+                         Offset.QuadPart >= 
PAGE_ROUND_UP(Segment->RawLength.QuadPart))) 
+       {
+               DPRINT("BSS Page\n");
+               Required->State = 2;
+               Required->Amount = 1;
+               Required->Consumer = MC_USER;
+               Required->DoAcquisition = MiGetOnePage;
                MmUnlockSectionSegment(Segment);
                return STATUS_MORE_PROCESSING_REQUIRED;
        }
@@ -690,6 +738,7 @@
    /*
     * Write the page to the pagefile
     */
+   DPRINT1("Writing swap entry: %x %x\n", SwapEntry, Page);
    Status = MmWriteToSwapPage(SwapEntry, Page);
    if (!NT_SUCCESS(Status))
    {
@@ -749,15 +798,22 @@
                ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
                if (SwapEntry == MM_WAIT_ENTRY)
                {
+                       DPRINT1
+                               ("SwapEntry is a WAIT, our swap to is %x, State 
is %x for (%x:%x) on page %x\n",
+                                Required->SwapEntry,
+                                Required->State,
+                                Process,
+                                Address,
+                                OurPage);                               
                        if (Required->SwapEntry || (Required->State & 2))
                        {
-                               MmDeleteRmap(OurPage, Process, Address);
                                Status = MmCreatePageFileMapping(Process, 
Address, Required->SwapEntry);
                                MmSetSavedSwapEntryPage(OurPage, 0);
                                ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
+                               MmDeleteRmap(OurPage, Process, Address);
                                MmDereferencePage(OurPage);
+                               MmUnlockSectionSegment(Segment);
                                KeSetEvent(&MmWaitPageEvent, IO_NO_INCREMENT, 
FALSE);
-                               MmUnlockSectionSegment(Segment);
                                ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
                                DPRINT("XXX Set Event %x\n", Status);
                                return Status;
@@ -780,37 +836,34 @@
                {
                        Required->State |= 2;
                        Required->SwapEntry = MmAllocSwapPage();
-                       if (!Required->SwapEntry) return STATUS_PAGEFILE_QUOTA;
+                       if (!Required->SwapEntry)
+                       {
+                               MmUnlockSectionSegment(Segment);
+                               return STATUS_PAGEFILE_QUOTA;
+                       }
+                       DPRINT1("MiWriteSwapPage (%x -> %x)\n", OurPage, 
Required->SwapEntry);
                        Required->DoAcquisition = MiWriteSwapPage;
                        MmCreatePageFileMapping(Process, Address, 
MM_WAIT_ENTRY);
                        MmUnlockSectionSegment(Segment);
                        return STATUS_MORE_PROCESSING_REQUIRED;
                }
-               else if (!Required->SwapEntry)
-               {
+               else
+               {
+                       DPRINT1("Out of swap space for page %x\n", OurPage);
                        MmUnlockSectionSegment(Segment);
                        return STATUS_PAGEFILE_QUOTA;
                }
-               MmDeleteRmap(OurPage, Process, Address);
-               MmCreatePageFileMapping(Process, Address, Required->SwapEntry);
-               MmDereferencePage(OurPage);
-               MmUnlockSectionSegment(Segment);
-               return STATUS_SUCCESS;
        }
        else
        {
                BOOLEAN Dirty = !!MmIsDirtyPageRmap(OurPage);
                Required->State |= Dirty;
                DPRINT("Public page evicting %x (dirty %d)\n", OurPage, 
Required->State & 1);
-               if (Dirty)
-               {
-                       DPRINT("Setting segment page dirty\n");
-                       MiSetPageEntrySectionSegment(Segment, &TotalOffset, 
DIRTY_SSE(Entry));
-               }
+               MmDeleteVirtualMapping(Process, Address, FALSE, NULL, NULL);
                MmDeleteRmap(OurPage, Process, Address);
-               MmDeleteVirtualMapping(Process, Address, FALSE, NULL, NULL);
                MmDereferencePage(OurPage);
                MmUnlockSectionSegment(Segment);
+               KeSetEvent(&MmWaitPageEvent, IO_NO_INCREMENT, FALSE);
                return STATUS_SUCCESS;
        }
 }

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=44944&r1=44943&r2=44944&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] Tue Jan  5 
16:15:30 2010
@@ -153,24 +153,20 @@
  BOOLEAN Dirty)
 {
        NTSTATUS Status = STATUS_SUCCESS;
-       SWAPENTRY Swap;
-
+       BOOLEAN WriteZero = FALSE;
+       SWAPENTRY Swap = MmGetSavedSwapEntryPage(Page);
+
+       MmLockSectionSegment(Segment);
        if (Dirty)
        {
-               DPRINT("Finalize (dirty) Segment %x\n", Segment);
+               DPRINT1("Finalize (dirty) Segment %x Page %x\n", Segment, Page);
                DPRINT("Segment->FileObject %x\n", Segment->FileObject);
                DPRINT("Segment->Flags %x\n", Segment->Flags);
                if (Segment->FileObject && !(Segment->Flags & MM_IMAGE_SEGMENT))
                {
-                       DPRINT("Segment %x FileObject %x\n", Segment, 
Segment->FileObject, &Segment);
+                       DPRINT1("Segment %x FileObject %x Offset %x\n", 
Segment, Segment->FileObject, FileOffset->LowPart);
                        Status = MiWriteBackPage(Segment->FileObject, 
FileOffset, PAGE_SIZE, Page);
-                       if (NT_SUCCESS(Status))
-                       {
-                               DPRINT("Write zero to %x:%x %x\n", Segment, 
FileOffset->LowPart, Page);
-                               MmLockSectionSegment(Segment);
-                               MiSetPageEntrySectionSegment(Segment, 
FileOffset, 0);
-                               MmUnlockSectionSegment(Segment);
-                       }
+                       WriteZero = NT_SUCCESS(Status);
                }
                else
                {
@@ -185,29 +181,36 @@
                        }
 
                        DPRINT("Status %x\n", Status);
-                       if (NT_SUCCESS(Status)) 
-                       {
-                               DPRINT("Set Swap entry\n");
-                               MmLockSectionSegment(Segment);
-                               MiSetPageEntrySectionSegment(Segment, 
FileOffset, MAKE_SWAP_SSE(Swap));
-                               MmUnlockSectionSegment(Segment);
-                       }
+                       WriteZero = NT_SUCCESS(Status);
                }
        }
        else
        {
-               DPRINT("Write zero to %x:%x (%x)\n", Segment, 
FileOffset->LowPart, Page);
-               MmLockSectionSegment(Segment);
-               MiSetPageEntrySectionSegment(Segment, FileOffset, 0);
-               MmUnlockSectionSegment(Segment);
+               WriteZero = TRUE;
        }
 
        DPRINT("Status %x\n", Status);
+
+       if (WriteZero)
+       {
+               DPRINT1("Setting page entry in segment %x:%x to swap %x\n", 
Segment, FileOffset->LowPart, Swap);
+               MiSetPageEntrySectionSegment(Segment, FileOffset, Swap ? 
MAKE_SWAP_SSE(Swap) : 0);
+       }
+       else
+       {
+               DPRINT1("Setting page entry in segment %x:%x to page %x\n", 
Segment, FileOffset->LowPart, Page);
+               MiSetPageEntrySectionSegment
+                       (Segment, FileOffset, Page ? (Dirty ? 
DIRTY_SSE(MAKE_PFN_SSE(Page)) : MAKE_PFN_SSE(Page)) : 0);
+       }
+
        if (NT_SUCCESS(Status))
        {
+               DPRINT1("Removing page %x for real\n", Page);
                MmSetSavedSwapEntryPage(Page, 0);
                MmDereferencePage(Page);
        }
+
+       MmUnlockSectionSegment(Segment);
 
        KeSetEvent(&MmWaitPageEvent, IO_NO_INCREMENT, FALSE);
 


Reply via email to