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/int…
==============================================================================
--- 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/de…
==============================================================================
--- 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/io…
==============================================================================
--- 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/ra…
==============================================================================
--- 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.…
==============================================================================
--- 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.…
==============================================================================
--- 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…
==============================================================================
--- 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?re…
==============================================================================
--- 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?r…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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);
}