Author: arty
Date: Tue Nov 24 18:45:24 2009
New Revision: 44281
URL:
http://svn.reactos.org/svn/reactos?rev=44281&view=rev
Log:
Deprecate old separate lazy write thread
Fix and enable MPW
Fix page op's hash function (really, |?)
Simplify section implementation to completely remove use of page ops in all section
types.
Yields a surprising speed improvement.
Modified:
branches/arty-newcc/ntoskrnl/cache/fssup.c
branches/arty-newcc/ntoskrnl/cache/lazyrite.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/pageop.c
branches/arty-newcc/ntoskrnl/mm/section/data.c
branches/arty-newcc/ntoskrnl/mm/section/image.c
branches/arty-newcc/ntoskrnl/mm/section/pagefile.c
Modified: branches/arty-newcc/ntoskrnl/cache/fssup.c
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/cache/fssup…
==============================================================================
--- branches/arty-newcc/ntoskrnl/cache/fssup.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/cache/fssup.c [iso-8859-1] Tue Nov 24 18:45:24 2009
@@ -17,12 +17,7 @@
PFSN_PREFETCHER_GLOBALS CcPfGlobals;
extern LONG CcOutstandingDeletes;
-extern KEVENT CcpLazyWriteEvent;
extern KEVENT CcFinalizeEvent;
-extern VOID NTAPI CcpUnmapThread(PVOID Unused);
-extern VOID NTAPI CcpLazyWriteThread(PVOID Unused);
-HANDLE CcUnmapThreadHandle, CcLazyWriteThreadHandle;
-CLIENT_ID CcUnmapThreadId, CcLazyWriteThreadId;
typedef struct _NOCC_PRIVATE_CACHE_MAP
{
@@ -48,7 +43,6 @@
KeInitializeEvent(&CcDeleteEvent, SynchronizationEvent, FALSE);
KeInitializeEvent(&CcFinalizeEvent, SynchronizationEvent, FALSE);
- KeInitializeEvent(&CcpLazyWriteEvent, SynchronizationEvent, FALSE);
CcCacheBitmap->Buffer = ((PULONG)&CcCacheBitmap[1]);
CcCacheBitmap->SizeOfBitMap = ROUND_UP(CACHE_NUM_SECTIONS, 32);
Modified: branches/arty-newcc/ntoskrnl/cache/lazyrite.c
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/cache/lazyr…
==============================================================================
--- branches/arty-newcc/ntoskrnl/cache/lazyrite.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/cache/lazyrite.c [iso-8859-1] Tue Nov 24 18:45:24 2009
@@ -14,21 +14,15 @@
/* GLOBALS ********************************************************************/
-KEVENT CcpLazyWriteEvent;
+extern KEVENT MpwCompleteEvent;
/* FUNCTIONS ******************************************************************/
-
-VOID NTAPI
-CcpLazyWriteThread(PVOID Unused)
-{
- /* Not implemented */
-}
NTSTATUS
NTAPI
CcWaitForCurrentLazyWriterActivity(VOID)
{
- //KeWaitForSingleObject(&CcpLazyWriteEvent, Executive, KernelMode, FALSE, NULL);
+ KeWaitForSingleObject(&MpwCompleteEvent, Executive, KernelMode, FALSE, NULL);
return STATUS_SUCCESS;
}
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] Tue Nov 24 18:45:24 2009
@@ -138,10 +138,7 @@
else
{
KeReleaseSpinLock(&AllocationListLock, OldIrql);
- if(Consumer == MC_USER) MmRemoveLRUUserPage(Page);
- OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
MmDereferencePage(Page);
- KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
}
return(STATUS_SUCCESS);
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] Tue Nov 24 18:45:24 2009
@@ -99,6 +99,7 @@
return 0;
}
PageDescriptor = CONTAINING_RECORD(NextListEntry, PHYSICAL_PAGE, ListEntry);
+ MmReferencePage(PageDescriptor - MmPfnDatabase);
ASSERT_PFN(PageDescriptor);
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
return PageDescriptor - MmPfnDatabase;
@@ -137,10 +138,13 @@
NextListEntry = (PLIST_ENTRY)Page->ListEntry.Flink;
if (NextListEntry == &UserPageListHead)
{
+ MmDereferencePage(PreviousPfn);
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
return 0;
}
PageDescriptor = CONTAINING_RECORD(NextListEntry, PHYSICAL_PAGE, ListEntry);
+ MmReferencePage(PageDescriptor - MmPfnDatabase);
+ MmDereferencePage(PreviousPfn);
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
return PageDescriptor - MmPfnDatabase;
}
@@ -906,6 +910,7 @@
NTAPI
MmDereferencePage(PFN_TYPE Pfn)
{
+ KIRQL oldIrql;
PPHYSICAL_PAGE Page;
DPRINT("MmDereferencePage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
@@ -928,7 +933,12 @@
if (Page->ReferenceCount == 0)
{
MmAvailablePages++;
- if (Page->Flags.Consumer == MC_USER) RemoveEntryList(&Page->ListEntry);
+ if (Page->Flags.Consumer == MC_USER)
+ {
+ oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+ RemoveEntryList(&Page->ListEntry);
+ KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
+ }
if (Page->RmapListHead != (LONG)NULL)
{
DPRINT1("Freeing page with rmap entries.\n");
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] Tue Nov 24 18:45:24 2009
@@ -18,7 +18,7 @@
HANDLE MpwThreadHandle;
static CLIENT_ID MpwThreadId;
-KEVENT MpwThreadEvent;
+KEVENT MpwThreadEvent, MpwCompleteEvent;
BOOLEAN MpwThreadShouldTerminate;
/* FUNCTIONS *****************************************************************/
@@ -81,12 +81,11 @@
}
PagesWritten = 0;
-#if 0
/*
* FIXME: MmWriteDirtyPages doesn't work correctly.
*/
MmWriteDirtyPages(128, &PagesWritten);
-#endif
+ KeSetEvent(&MpwCompleteEvent, IO_NO_INCREMENT, TRUE);
}
}
@@ -99,6 +98,7 @@
MpwThreadShouldTerminate = FALSE;
KeInitializeEvent(&MpwThreadEvent, SynchronizationEvent, FALSE);
+ KeInitializeEvent(&MpwCompleteEvent, SynchronizationEvent, FALSE);
Status = PsCreateSystemThread(&MpwThreadHandle,
THREAD_ALL_ACCESS,
Modified: branches/arty-newcc/ntoskrnl/mm/pageop.c
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/pageop.c…
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/pageop.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/pageop.c [iso-8859-1] Tue Nov 24 18:45:24 2009
@@ -83,11 +83,11 @@
*/
if (MArea->Type == MEMORY_AREA_SECTION_VIEW)
{
- Hash = (((ULONG_PTR)Segment) | (((ULONG_PTR)Offset) / PAGE_SIZE));
+ Hash = (((ULONG_PTR)Segment) ^ (((ULONG_PTR)Offset) / PAGE_SIZE));
}
else
{
- Hash = (((ULONG_PTR)Pid) | (((ULONG_PTR)Address) / PAGE_SIZE));
+ Hash = (((ULONG_PTR)Pid) ^ (((ULONG_PTR)Address) / PAGE_SIZE));
}
Hash = Hash % PAGEOP_HASH_TABLE_SIZE;
@@ -151,11 +151,11 @@
*/
if (MArea->Type == MEMORY_AREA_SECTION_VIEW)
{
- Hash = (((ULONG_PTR)Segment) | (((ULONG_PTR)Offset) / PAGE_SIZE));
+ Hash = (((ULONG_PTR)Segment) ^ (((ULONG_PTR)Offset) / PAGE_SIZE));
}
else
{
- Hash = (((ULONG_PTR)Pid) | (((ULONG_PTR)Address) / PAGE_SIZE));
+ Hash = (((ULONG_PTR)Pid) ^ (((ULONG_PTR)Address) / PAGE_SIZE));
}
Hash = Hash % PAGEOP_HASH_TABLE_SIZE;
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] Tue Nov 24 18:45:24 2009
@@ -2333,50 +2333,6 @@
return(STATUS_SUCCESS);
}
-NTSTATUS
-NTAPI
-MiAwaitPageOps(PMMSUPPORT AddressSpace, PMEMORY_AREA MemoryArea, PVOID BaseAddress)
-{
- NTSTATUS Status;
- PMM_PAGEOP PageOp;
- ULONG Offset;
-
- while (MemoryArea->PageOpCount)
- {
- Offset = PAGE_ROUND_UP((ULONG_PTR)MemoryArea->EndingAddress -
(ULONG_PTR)MemoryArea->StartingAddress);
-
- while (Offset)
- {
- Offset -= PAGE_SIZE;
- PageOp = MmCheckForPageOp(MemoryArea, NULL, NULL,
- MemoryArea->Data.SectionData.Segment,
- Offset);
- if (PageOp)
- {
- MmUnlockAddressSpace(AddressSpace);
- Status = MmspWaitForPageOpCompletionEvent(PageOp);
- if (Status != STATUS_SUCCESS)
- {
- DPRINT1("Failed to wait for page op, status = %x\n", Status);
- ASSERT(FALSE);
- }
- MmLockAddressSpace(AddressSpace);
- MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace,
- BaseAddress);
- if (MemoryArea == NULL ||
- MemoryArea->Type != MEMORY_AREA_SECTION_VIEW)
- {
- MmUnlockAddressSpace(AddressSpace);
- DPRINT("STATUS_NOT_MAPPED_VIEW\n");
- return STATUS_NOT_MAPPED_VIEW;
- }
- break;
- }
- }
- }
- return STATUS_SUCCESS;
-}
-
/*
* @implemented
*/
@@ -2409,18 +2365,14 @@
if (MemoryArea->Type == MEMORY_AREA_IMAGE_SECTION)
{
MemoryArea->DeleteInProgress = TRUE;
- Status = MiAwaitPageOps(AddressSpace, MemoryArea, BaseAddress);
- if (NT_SUCCESS(Status))
- Status = MiUnmapImageSection(AddressSpace, MemoryArea, BaseAddress);
+ Status = MiUnmapImageSection(AddressSpace, MemoryArea, BaseAddress);
}
else if (MemoryArea->Type == MEMORY_AREA_PHYSICAL_MEMORY_SECTION ||
MemoryArea->Type == MEMORY_AREA_PAGE_FILE_SECTION ||
MemoryArea->Type == MEMORY_AREA_SECTION_VIEW)
{
MemoryArea->DeleteInProgress = TRUE;
- Status = MiAwaitPageOps(AddressSpace, MemoryArea, BaseAddress);
- if (NT_SUCCESS(Status))
- Status = MmUnmapViewOfSegment(AddressSpace, BaseAddress);
+ Status = MmUnmapViewOfSegment(AddressSpace, BaseAddress);
}
else
{
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] Tue Nov 24 18:45:24 2009
@@ -1848,8 +1848,6 @@
//DPRINT("MiUnmapImageSection @ %x\n", BaseAddress);
MemoryArea->DeleteInProgress = TRUE;
- MiAwaitPageOps(AddressSpace, MemoryArea, BaseAddress);
-
Section = MemoryArea->Data.SectionData.Section;
if (Section->AllocationAttributes & SEC_IMAGE)
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] Tue Nov 24 18:45:24
2009
@@ -69,9 +69,7 @@
PROS_SECTION_OBJECT Section;
PMM_SECTION_SEGMENT Segment;
ULONG Entry;
- ULONG Entry1;
ULONG Attributes;
- PMM_PAGEOP PageOp;
PMM_REGION Region;
BOOLEAN HasSwapEntry;
PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
@@ -100,10 +98,14 @@
Region = MmFindRegion(MemoryArea->StartingAddress,
&MemoryArea->Data.SectionData.RegionListHead,
Address, NULL);
+
/*
* Lock the segment
*/
MmLockSectionSegment(Segment);
+
+ Entry = MiGetPageEntrySectionSegment(Segment, &Offset);
+ HasSwapEntry = MmIsPageSwapEntry(Process, (PVOID)PAddress);
/*
* Check if this page needs to be mapped COW
@@ -119,161 +121,38 @@
Attributes = Region->Protect;
}
- /*
- * Get or create a page operation descriptor
- */
- PageOp = MmGetPageOp(MemoryArea, NULL, 0, Segment, Offset.QuadPart, MM_PAGEOP_PAGEIN,
FALSE);
- if (PageOp == NULL)
- {
- DPRINT1("MmGetPageOp failed\n");
- ASSERT(FALSE);
- }
-
- /*
- * Check if someone else is already handling this fault, if so wait
- * for them
- */
- if (PageOp->Thread != PsGetCurrentThread())
- {
- MmUnlockSectionSegment(Segment);
- MmUnlockAddressSpace(AddressSpace);
- Status = MmspWaitForPageOpCompletionEvent(PageOp);
- /*
- * Check for various strange conditions
- */
- if (Status != STATUS_SUCCESS)
- {
- DPRINT1("Failed to wait for page op, status = %x\n", Status);
- ASSERT(FALSE);
- }
- if (PageOp->Status == STATUS_PENDING)
- {
- DPRINT1("Woke for page op before completion\n");
- ASSERT(FALSE);
- }
- MmLockAddressSpace(AddressSpace);
- /*
- * If this wasn't a pagein then restart the operation
- */
- if (PageOp->OpType != MM_PAGEOP_PAGEIN)
- {
- MmspCompleteAndReleasePageOp(PageOp);
- DPRINT("Address 0x%.8X\n", Address);
- return(STATUS_MM_RESTART_OPERATION);
- }
-
- /*
- * If the thread handling this fault has failed then we don't retry
- */
- if (!NT_SUCCESS(PageOp->Status))
- {
- Status = PageOp->Status;
- MmspCompleteAndReleasePageOp(PageOp);
- DPRINT("Address 0x%.8X\n", Address);
- return(Status);
- }
- MmLockSectionSegment(Segment);
- /*
- * If the completed fault was for another address space then set the
- * page in this one.
- */
- if (!MmIsPagePresent(Process, Address))
- {
- DPRINT("!MmIsPagePresent(%p, %p)\n", Process, Address);
-
- Entry = MiGetPageEntrySectionSegment(Segment, &Offset);
- HasSwapEntry = MmIsPageSwapEntry(Process, (PVOID)PAddress);
-
- if (PAGE_FROM_SSE(Entry) == 0 || HasSwapEntry)
- {
- /*
- * The page was a private page in another or in our address space
- */
- MmUnlockSectionSegment(Segment);
- MmspCompleteAndReleasePageOp(PageOp);
- return(STATUS_MM_RESTART_OPERATION);
- }
-
- Page = PFN_FROM_SSE(Entry);
-
- MmSharePageEntrySectionSegment(Segment, &Offset);
-
- /* FIXME: Should we call MmCreateVirtualMappingUnsafe if
- * (Section->AllocationAttributes & SEC_PHYSICALMEMORY) is true?
- */
- Status = MmCreateVirtualMapping(Process,
- Address,
- Attributes,
- &Page,
- 1);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Unable to create virtual mapping\n");
- ASSERT(FALSE);
- }
- MmInsertRmap(Page, Process, (PVOID)PAddress);
- }
- if (Locked)
- {
- MmLockPage(Page);
- }
- MmUnlockSectionSegment(Segment);
- PageOp->Status = STATUS_SUCCESS;
- MmspCompleteAndReleasePageOp(PageOp);
- DPRINT("Address 0x%.8X\n", Address);
- return(STATUS_SUCCESS);
- }
-
- /*
- * Get the entry corresponding to the offset within the section
- */
- Entry = MiGetPageEntrySectionSegment(Segment, &Offset);
-
if (Entry == 0)
{
- /*
- * If the entry is zero (and it can't change because we have
- * locked the segment) then we need to load the page.
- */
-
- /*
- * Release all our locks and read in the page from disk
- */
- MmUnlockSectionSegment(Segment);
MmUnlockAddressSpace(AddressSpace);
-
Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page);
if (!NT_SUCCESS(Status))
{
DPRINT1("MmRequestPageMemoryConsumer failed (Status %x)\n", Status);
+ MmLockAddressSpace(AddressSpace);
+ MmUnlockSectionSegment(Segment);
+ return Status;
}
+
+ DPRINT("Allocated page %x\n", Page);
Status = MmCreateVirtualMapping(Process,
- Address,
+ PAddress,
Attributes,
&Page,
1);
if (!NT_SUCCESS(Status))
{
DPRINT1("Unable to create virtual mapping\n");
- ASSERT(FALSE);
+ MmReleasePageMemoryConsumer(MC_USER, Page);
+ DPRINT("Release page %x\n", Page);
+ MmLockAddressSpace(AddressSpace);
+ MmUnlockSectionSegment(Segment);
+ return Status;
}
/*
* Relock the address space and segment
*/
MmLockAddressSpace(AddressSpace);
- MmLockSectionSegment(Segment);
-
- /*
- * Check the entry. No one should change the status of a page
- * that has a pending page-in.
- */
- Entry1 = MiGetPageEntrySectionSegment(Segment, &Offset);
- if (Entry != Entry1)
- {
- DPRINT1("Someone changed ppte entry while we slept\n");
- ASSERT(FALSE);
- }
/*
* Mark the offset within the section as having valid, in-memory
@@ -281,16 +160,14 @@
*/
Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
MiSetPageEntrySectionSegment(Segment, &Offset, Entry);
- MmUnlockSectionSegment(Segment);
-
MmInsertRmap(Page, Process, (PVOID)PAddress);
if (Locked)
{
MmLockPage(Page);
}
- PageOp->Status = STATUS_SUCCESS;
- MmspCompleteAndReleasePageOp(PageOp);
+
+ MmUnlockSectionSegment(Segment);
DPRINT("Address 0x%.8X\n", Address);
return(STATUS_SUCCESS);
}
@@ -302,8 +179,6 @@
{
MmLockPage(Page);
}
- PageOp->Status = Status;
- MmspCompleteAndReleasePageOp(PageOp);
return Status;
}
else
@@ -333,8 +208,6 @@
{
MmLockPage(Page);
}
- PageOp->Status = STATUS_SUCCESS;
- MmspCompleteAndReleasePageOp(PageOp);
DPRINT("Address 0x%.8X\n", Address);
return(STATUS_SUCCESS);
}
@@ -699,8 +572,6 @@
PFN_TYPE Page, SWAPENTRY SwapEntry, BOOLEAN Dirty)
{
ULONG Entry;
- PMM_PAGEOP PageOp;
- NTSTATUS Status;
LARGE_INTEGER Offset;
PROS_SECTION_OBJECT Section;
PMM_SECTION_SEGMENT Segment;
@@ -717,26 +588,6 @@
Section = MemoryArea->Data.SectionData.Section;
Segment = MemoryArea->Data.SectionData.Segment;
-
- PageOp = MmCheckForPageOp(MemoryArea, NULL, NULL, Segment, Offset.QuadPart);
-
- while (PageOp)
- {
- MmUnlockSectionSegment(Segment);
- MmUnlockAddressSpace(AddressSpace);
-
- Status = MmspWaitForPageOpCompletionEvent(PageOp);
- if (Status != STATUS_SUCCESS)
- {
- DPRINT1("Failed to wait for page op, status = %x\n", Status);
- ASSERT(FALSE);
- }
-
- MmLockAddressSpace(AddressSpace);
- MmLockSectionSegment(Segment);
- MmspCompleteAndReleasePageOp(PageOp);
- PageOp = MmCheckForPageOp(MemoryArea, NULL, NULL, Segment, Offset.QuadPart);
- }
DPRINT("MmFreeSectionPage -> MmGetPageEntrySectionSegment(%p, %x)\n",
Segment, Offset.u.LowPart);
Entry = MiGetPageEntrySectionSegment(Segment, &Offset);