[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 1998-2005 ReactOS Team (and the authors from the programmers section)
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* PROJECT: ReactOS kernel
|
2015-10-04 11:54:25 +00:00
|
|
|
* FILE: ntoskrnl/cache/section/fault.c
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
* PURPOSE: Consolidate fault handlers for sections
|
|
|
|
*
|
|
|
|
* PROGRAMMERS: Arty
|
|
|
|
* Rex Jolliff
|
|
|
|
* David Welch
|
|
|
|
* Eric Kohl
|
|
|
|
* Emanuele Aliberti
|
|
|
|
* Eugene Ingerman
|
|
|
|
* Casper Hornstrup
|
|
|
|
* KJK::Hyperion
|
|
|
|
* Guido de Jong
|
|
|
|
* Ge van Geldorp
|
|
|
|
* Royce Mitchell III
|
|
|
|
* Filip Navara
|
|
|
|
* Aleksey Bragin
|
|
|
|
* Jason Filby
|
|
|
|
* Thomas Weidenmueller
|
|
|
|
* Gunnar Andre' Dalsnes
|
|
|
|
* Mike Nordell
|
|
|
|
* Alex Ionescu
|
|
|
|
* Gregor Anich
|
|
|
|
* Steven Edwards
|
|
|
|
* Herve Poussineau
|
|
|
|
*/
|
|
|
|
|
2012-03-29 04:43:44 +00:00
|
|
|
/*
|
|
|
|
|
|
|
|
I've generally organized fault handling code in newmm as handlers that run
|
|
|
|
under a single lock acquisition, check the state, and either take necessary
|
|
|
|
action atomically, or place a wait entry and return a continuation to the
|
|
|
|
caller. This lends itself to code that has a simple, structured form,
|
|
|
|
doesn't make assumptions about lock taking and breaking, and provides an
|
|
|
|
obvious, graphic seperation between code that may block and code that isn't
|
2012-03-29 12:14:58 +00:00
|
|
|
allowed to. This file contains the non-blocking half.
|
2012-03-29 04:43:44 +00:00
|
|
|
|
2012-03-29 12:14:58 +00:00
|
|
|
In order to request a blocking operation to happen outside locks, place a
|
2012-03-29 04:43:44 +00:00
|
|
|
function pointer in the provided MM_REQUIRED_RESOURCES struct and return
|
|
|
|
STATUS_MORE_PROCESSING_REQUIRED. The function indicated will receive the
|
|
|
|
provided struct and take action outside of any mm related locks and at
|
|
|
|
PASSIVE_LEVEL. The same fault handler will be called again after the
|
|
|
|
blocking operation succeeds. In this way, the fault handler can accumulate
|
|
|
|
state, but will freely work while competing with other threads.
|
|
|
|
|
|
|
|
Fault handlers in this file should check for an MM_WAIT_ENTRY in a page
|
|
|
|
table they're using and return STATUS_SUCCESS + 1 if it's found. In that
|
|
|
|
case, the caller will wait on the wait entry event until the competing thread
|
|
|
|
is finished, and recall this handler in the current thread.
|
|
|
|
|
|
|
|
Another thing to note here is that we require mappings to exactly mirror
|
|
|
|
rmaps, so each mapping should be immediately followed by an rmap addition.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
/* INCLUDES *****************************************************************/
|
|
|
|
|
|
|
|
#include <ntoskrnl.h>
|
|
|
|
#include "newmm.h"
|
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
2014-11-10 16:26:55 +00:00
|
|
|
#include <mm/ARM3/miarm.h>
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
|
|
|
|
#define DPRINTC DPRINT
|
|
|
|
|
|
|
|
extern KEVENT MmWaitPageEvent;
|
2012-02-24 10:05:06 +00:00
|
|
|
extern PMMWSL MmWorkingSetList;
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
|
2012-03-29 04:43:44 +00:00
|
|
|
/*
|
|
|
|
|
|
|
|
Multiple stage handling of a not-present fault in a data section.
|
|
|
|
|
|
|
|
Required->State is used to accumulate flags that indicate the next action
|
2012-03-29 12:14:58 +00:00
|
|
|
the handler should take.
|
2012-03-29 04:43:44 +00:00
|
|
|
|
|
|
|
State & 2 is currently used to indicate that the page acquired by a previous
|
|
|
|
callout is a global page to the section and should be placed in the section
|
|
|
|
page table.
|
|
|
|
|
|
|
|
Note that the primitive tail recursion done here reaches the base case when
|
|
|
|
the page is present.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
2012-12-19 23:49:13 +00:00
|
|
|
MmNotPresentFaultCachePage (
|
|
|
|
_In_ PMMSUPPORT AddressSpace,
|
|
|
|
_In_ MEMORY_AREA* MemoryArea,
|
|
|
|
_In_ PVOID Address,
|
|
|
|
_In_ BOOLEAN Locked,
|
|
|
|
_Inout_ PMM_REQUIRED_RESOURCES Required)
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
{
|
2012-03-28 18:39:21 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
PVOID PAddress;
|
|
|
|
ULONG Consumer;
|
|
|
|
PMM_SECTION_SEGMENT Segment;
|
|
|
|
LARGE_INTEGER FileOffset, TotalOffset;
|
2012-03-28 19:41:40 +00:00
|
|
|
ULONG_PTR Entry;
|
2012-03-28 18:39:21 +00:00
|
|
|
ULONG Attributes;
|
|
|
|
PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
|
|
|
|
KIRQL OldIrql;
|
|
|
|
|
|
|
|
DPRINT("Not Present: %p %p (%p-%p)\n",
|
|
|
|
AddressSpace,
|
|
|
|
Address,
|
2015-05-16 20:10:03 +00:00
|
|
|
MA_GetStartingAddress(MemoryArea),
|
2015-05-16 20:10:26 +00:00
|
|
|
MA_GetEndingAddress(MemoryArea));
|
2012-03-28 18:39:21 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* There is a window between taking the page fault and locking the
|
|
|
|
* address space when another thread could load the page so we check
|
|
|
|
* that.
|
|
|
|
*/
|
|
|
|
if (MmIsPagePresent(Process, Address))
|
|
|
|
{
|
|
|
|
DPRINT("Done\n");
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
|
|
|
|
TotalOffset.QuadPart = (ULONG_PTR)PAddress -
|
2015-05-16 20:10:03 +00:00
|
|
|
MA_GetStartingAddress(MemoryArea);
|
2012-03-28 18:39:21 +00:00
|
|
|
|
|
|
|
Segment = MemoryArea->Data.SectionData.Segment;
|
|
|
|
|
|
|
|
TotalOffset.QuadPart += MemoryArea->Data.SectionData.ViewOffset.QuadPart;
|
|
|
|
FileOffset = TotalOffset;
|
|
|
|
|
|
|
|
//Consumer = (Segment->Flags & MM_DATAFILE_SEGMENT) ? MC_CACHE : MC_USER;
|
|
|
|
Consumer = MC_CACHE;
|
|
|
|
|
|
|
|
if (Segment->FileObject)
|
|
|
|
{
|
|
|
|
DPRINT("FileName %wZ\n", &Segment->FileObject->FileName);
|
|
|
|
}
|
|
|
|
|
|
|
|
DPRINT("Total Offset %08x%08x\n", TotalOffset.HighPart, TotalOffset.LowPart);
|
|
|
|
|
|
|
|
/* Lock the segment */
|
|
|
|
MmLockSectionSegment(Segment);
|
|
|
|
|
|
|
|
/* Get the entry corresponding to the offset within the section */
|
|
|
|
Entry = MmGetPageEntrySectionSegment(Segment, &TotalOffset);
|
|
|
|
|
|
|
|
Attributes = PAGE_READONLY;
|
|
|
|
|
|
|
|
if (Required->State && Required->Page[0])
|
|
|
|
{
|
|
|
|
DPRINT("Have file and page, set page %x in section @ %x #\n",
|
|
|
|
Required->Page[0],
|
|
|
|
TotalOffset.LowPart);
|
|
|
|
|
|
|
|
if (Required->SwapEntry)
|
|
|
|
MmSetSavedSwapEntryPage(Required->Page[0], Required->SwapEntry);
|
|
|
|
|
|
|
|
if (Required->State & 2)
|
|
|
|
{
|
|
|
|
DPRINT("Set in section @ %x\n", TotalOffset.LowPart);
|
|
|
|
Status = MmSetPageEntrySectionSegment(Segment,
|
|
|
|
&TotalOffset,
|
|
|
|
Entry = MAKE_PFN_SSE(Required->Page[0]));
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
MmReleasePageMemoryConsumer(MC_CACHE, Required->Page[0]);
|
|
|
|
}
|
|
|
|
MmUnlockSectionSegment(Segment);
|
|
|
|
MiSetPageEvent(Process, Address);
|
|
|
|
DPRINT("Status %x\n", Status);
|
|
|
|
return STATUS_MM_RESTART_OPERATION;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-02-16 17:37:17 +00:00
|
|
|
DPRINT("Set %x in address space @ %p\n", Required->Page[0], Address);
|
2012-03-28 18:39:21 +00:00
|
|
|
Status = MmCreateVirtualMapping(Process,
|
|
|
|
Address,
|
|
|
|
Attributes,
|
|
|
|
Required->Page,
|
|
|
|
1);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
MmInsertRmap(Required->Page[0], Process, Address);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Drop the reference for our address space ... */
|
|
|
|
MmReleasePageMemoryConsumer(MC_CACHE, Required->Page[0]);
|
|
|
|
}
|
|
|
|
MmUnlockSectionSegment(Segment);
|
|
|
|
DPRINTC("XXX Set Event %x\n", Status);
|
|
|
|
MiSetPageEvent(Process, Address);
|
|
|
|
DPRINT("Status %x\n", Status);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (MM_IS_WAIT_PTE(Entry))
|
|
|
|
{
|
2012-03-29 04:43:44 +00:00
|
|
|
// Whenever MM_WAIT_ENTRY is required as a swap entry, we need to
|
|
|
|
// ask the fault handler to wait until we should continue. Rathern
|
|
|
|
// than recopy this boilerplate code everywhere, we just ask them
|
|
|
|
// to wait.
|
2012-03-28 18:39:21 +00:00
|
|
|
MmUnlockSectionSegment(Segment);
|
|
|
|
return STATUS_SUCCESS + 1;
|
|
|
|
}
|
|
|
|
else if (Entry)
|
|
|
|
{
|
|
|
|
PFN_NUMBER Page = PFN_FROM_SSE(Entry);
|
|
|
|
DPRINT("Take reference to page %x #\n", Page);
|
|
|
|
|
|
|
|
if (MiGetPfnEntry(Page) == NULL)
|
|
|
|
{
|
|
|
|
DPRINT1("Found no PFN entry for page 0x%x in page entry 0x%x (segment: 0x%p, offset: %08x%08x)\n",
|
|
|
|
Page,
|
|
|
|
Entry,
|
|
|
|
Segment,
|
|
|
|
TotalOffset.HighPart,
|
|
|
|
TotalOffset.LowPart);
|
|
|
|
KeBugCheck(CACHE_MANAGER);
|
|
|
|
}
|
|
|
|
|
2017-11-21 22:33:42 +00:00
|
|
|
OldIrql = MiAcquirePfnLock();
|
2012-03-28 18:39:21 +00:00
|
|
|
MmReferencePage(Page);
|
2017-11-21 22:33:42 +00:00
|
|
|
MiReleasePfnLock(OldIrql);
|
2012-03-28 18:39:21 +00:00
|
|
|
|
|
|
|
Status = MmCreateVirtualMapping(Process, Address, Attributes, &Page, 1);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
MmInsertRmap(Page, Process, Address);
|
|
|
|
}
|
|
|
|
DPRINT("XXX Set Event %x\n", Status);
|
|
|
|
MiSetPageEvent(Process, Address);
|
|
|
|
MmUnlockSectionSegment(Segment);
|
|
|
|
DPRINT("Status %x\n", Status);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPRINT("Get page into section\n");
|
|
|
|
/*
|
|
|
|
* If the entry is zero (and it can't change because we have
|
|
|
|
* locked the segment) then we need to load the page.
|
|
|
|
*/
|
|
|
|
//DPRINT1("Read from file %08x %wZ\n", FileOffset.LowPart, &Section->FileObject->FileName);
|
|
|
|
Required->State = 2;
|
|
|
|
Required->Context = Segment->FileObject;
|
|
|
|
Required->Consumer = Consumer;
|
|
|
|
Required->FileOffset = FileOffset;
|
|
|
|
Required->Amount = PAGE_SIZE;
|
|
|
|
Required->DoAcquisition = MiReadFilePage;
|
|
|
|
|
|
|
|
MmSetPageEntrySectionSegment(Segment,
|
|
|
|
&TotalOffset,
|
|
|
|
MAKE_SWAP_SSE(MM_WAIT_ENTRY));
|
|
|
|
|
|
|
|
MmUnlockSectionSegment(Segment);
|
|
|
|
return STATUS_MORE_PROCESSING_REQUIRED;
|
|
|
|
}
|
|
|
|
ASSERT(FALSE);
|
|
|
|
return STATUS_ACCESS_VIOLATION;
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
MiCopyPageToPage(PFN_NUMBER DestPage, PFN_NUMBER SrcPage)
|
|
|
|
{
|
|
|
|
PEPROCESS Process;
|
|
|
|
KIRQL Irql, Irql2;
|
|
|
|
PVOID TempAddress, TempSource;
|
2012-03-28 18:39:21 +00:00
|
|
|
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
Process = PsGetCurrentProcess();
|
|
|
|
TempAddress = MiMapPageInHyperSpace(Process, DestPage, &Irql);
|
|
|
|
if (TempAddress == NULL)
|
|
|
|
{
|
2012-03-28 18:39:21 +00:00
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
}
|
|
|
|
TempSource = MiMapPageInHyperSpace(Process, SrcPage, &Irql2);
|
|
|
|
if (!TempSource) {
|
|
|
|
MiUnmapPageInHyperSpace(Process, TempAddress, Irql);
|
|
|
|
return STATUS_NO_MEMORY;
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(TempAddress, TempSource, PAGE_SIZE);
|
|
|
|
|
2012-03-28 18:39:21 +00:00
|
|
|
MiUnmapPageInHyperSpace(Process, TempSource, Irql2);
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
MiUnmapPageInHyperSpace(Process, TempAddress, Irql);
|
2012-03-28 18:39:21 +00:00
|
|
|
return STATUS_SUCCESS;
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
}
|
|
|
|
|
2012-03-29 04:43:44 +00:00
|
|
|
/*
|
|
|
|
|
|
|
|
This function is deceptively named, in that it does the actual work of handling
|
|
|
|
access faults on data sections. In the case of the code that's present here,
|
|
|
|
we don't allow cow sections, but we do need this to unset the initial
|
|
|
|
PAGE_READONLY condition of pages faulted into the cache so that we can add
|
|
|
|
a dirty bit in the section page table on the first modification.
|
|
|
|
|
|
|
|
In the ultimate form of this code, CoW is reenabled.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
2012-12-19 23:49:13 +00:00
|
|
|
MiCowCacheSectionPage (
|
|
|
|
_In_ PMMSUPPORT AddressSpace,
|
|
|
|
_In_ PMEMORY_AREA MemoryArea,
|
|
|
|
_In_ PVOID Address,
|
|
|
|
_In_ BOOLEAN Locked,
|
|
|
|
_Inout_ PMM_REQUIRED_RESOURCES Required)
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
{
|
2012-03-28 18:39:21 +00:00
|
|
|
PMM_SECTION_SEGMENT Segment;
|
|
|
|
PFN_NUMBER NewPage, OldPage;
|
|
|
|
NTSTATUS Status;
|
|
|
|
PVOID PAddress;
|
|
|
|
LARGE_INTEGER Offset;
|
|
|
|
PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
|
|
|
|
|
2013-02-16 17:37:17 +00:00
|
|
|
DPRINT("MmAccessFaultSectionView(%p, %p, %p, %u)\n",
|
2012-03-28 18:39:21 +00:00
|
|
|
AddressSpace,
|
|
|
|
MemoryArea,
|
|
|
|
Address,
|
|
|
|
Locked);
|
|
|
|
|
|
|
|
Segment = MemoryArea->Data.SectionData.Segment;
|
|
|
|
|
|
|
|
/* Lock the segment */
|
|
|
|
MmLockSectionSegment(Segment);
|
|
|
|
|
|
|
|
/* Find the offset of the page */
|
|
|
|
PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
|
2015-05-16 20:10:03 +00:00
|
|
|
Offset.QuadPart = (ULONG_PTR)PAddress - MA_GetStartingAddress(MemoryArea) +
|
2012-03-28 18:39:21 +00:00
|
|
|
MemoryArea->Data.SectionData.ViewOffset.QuadPart;
|
|
|
|
|
|
|
|
if (!Segment->WriteCopy /*&&
|
|
|
|
!MemoryArea->Data.SectionData.WriteCopyView*/ ||
|
|
|
|
Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED)
|
|
|
|
{
|
[NEWCC]
A reintegration checkpoint for the NewCC branch, brought to you by Team NewCC.
Differences with current ReactOS trunk:
* A new memory area type, MEMORY_AREA_CACHE, is added, which represents a mapped region of a file. In NEWCC mode, user sections are MEMORY_AREA_CACHE type as well, and obey new semantics. In non-NEWCC mode, they aren't used.
* A way of claiming a page entry for a specific thread's work is added. Placing the special SWAPENTRY value MM_WAIT_ENTRY in a page table, or in a section page table should indicate that memory management code is intended to wait for another thread to make some status change before checking the state of the page entry again. In code that uses this convention, a return value of STATUS_SUCCESS + 1 is used to indicate that the caller should use the MiWaitForPageEvent macro to wait until somebody has change the state of a wait entry before checking again. This is a lighter weight mechanism than PAGEOPs.
* A way of asking the caller to perform some blocking operation without locks held is provided. This replaces some spaghettified code in which locks are repeatedly taken and broken by code that performs various blocking operations. Using this mechanism, it is possible to do a small amount of non-blocking work, fill in a request, then return STATUS_MORE_PROCESSING_REQUIRED to request that locks be dropped and the blocking operation be carried out. A MM_REQUIRED_RESOURCES structure is provided to consumers of this contract to use to accumulate state across many blocking operations. Several functions wrapping blocking operations are provided in ntoskrnl/cache/reqtools.c.
* Image section pages are no longer direct mapped. This is done to simplify consolidation of ownership of pages under the data section system. At a later time, it may be possible to make data pages directly available to image sections for the same file. This is likely the only direct performance impact this code makes on non-NEWCC mode.
RMAPs:
* A new type of RMAP entry is introduced, distinguished by RMAP_IS_SEGMENT(Address) of the rmap entry. This kind of entry contains a pointer to a section page table node in the Process pointer, which in turn links back to the MM_SECTION_SEGMENT it belongs to. Therefore, a page belonging only to a segment (that is, a segment page that isn't mapped) can exist and be evicted using the normal page eviction mechanism in balance.c. Each of the rmap function has been modified to deal with segment rmaps.
* The low 8 bits of the Address field in a segment rmap denote the entry number in the generic table node pointed to by Process that points to the page the rmap belongs to. By combining them, you can determine the file offset the page belongs to.
* In NEWCC mode, MmSharePageEntry/UnsharePageEntry are not used, and instead the page reference count is used to keep track of the number of mappings of a page, allowing the last reference expiring to allow the page to be recycled without much intervention. These are still used in non-NEWCC mode. One change has been made, the count fields have been narrowed by 1 bit to make room for a dirty bit in SSE entries, needed when a page is present but unmapped.
Section page tables:
* The section page tables are now implemented using RtlGenericTables. This enables a fairly compact representation of section page tables without having the existence of a section object imply 4k of fake PDEs. In addition, each node in the generic table has a wide file offset that is a multiple of 256 pages, or 1 megabyte total. Besides needing wide file offsets, the only other visible change caused by the switch to generic tables for section page tables is the need to lock the section segment before interacting with the section page table.
Eviction:
* Page eviction in cache sections is accomplished by MmpPageOutPhysicalAddress. In the case of a shared page, it tries to remove all mappings of the indicated page. If this process fails at any point, the page will simply be drawn back into the target address spaces. After succeeding at this, if TRUE has been accumulated into the page's dirty bit in the section page table, it is written back, and then permanently removed.
NewCC mode:
* NEWCC mode is introduced, which rewrites the file cache to a set of cache stripes actively mapped, along with unmapped section data.
* NewCC is more authentic in its interpretation of the external interface to the windows cache than the current cache manager, implementing each of the cache manager functions according to the documented interface with no preconceived ideas about how anything should be implemented internally. Cache stripes are implemented on top of section objects, using the same memory manager paths, and therefore economizing code and complexity. This replaces a rather complicated system in which pages can be owned by the cache manager and the memory manager simultaneously and they must cooperate in a fairly sophisticated way to manage them. Since they're quite interdependent in the current code, modifying either is very difficult. In NEWCC, they have a clear division of labor and thus can be worked on independently.
* Several third party filesystems that use the kernel Cc interface work properly using NEWCC, including matt wu's ext3 driver.
* In contrast with code that tries to make CcInitializeCacheMap and CcUninitializeCacheMap into a pair that supports reference counting, NEWCC lazily initializes the shared and private cache maps as needed and uses the presence of a PrivateCacheMap on at least one file pointing to the SharedCacheMap as an indication that the FILE_OBJECT reference in the SharedCacheMap should still be held. When the last PrivateCacheMap is discarded, that's the appropriate time to tear down caching for a specific file, as the SharedCacheMap data is allowed to be saved and reused. We honor this by making the SharedCacheMap into a depot for keeping track of the PrivateCacheMap objects associated with views of a file.
svn path=/trunk/; revision=55833
2012-02-23 12:03:06 +00:00
|
|
|
#if 0
|
2012-03-29 12:14:58 +00:00
|
|
|
if (Region->Protect == PAGE_READWRITE ||
|
2012-03-28 18:39:21 +00:00
|
|
|
Region->Protect == PAGE_EXECUTE_READWRITE)
|
2010-11-11 08:15:50 +00:00
|
|
|
#endif
|
2012-03-28 18:39:21 +00:00
|
|
|
{
|
2012-03-28 19:41:40 +00:00
|
|
|
ULONG_PTR Entry;
|
2013-02-16 17:37:17 +00:00
|
|
|
DPRINTC("setting non-cow page %p %p:%p offset %I64x (%Ix) to writable\n",
|
2012-03-28 18:39:21 +00:00
|
|
|
Segment,
|
|
|
|
Process,
|
|
|
|
PAddress,
|
2013-02-16 17:37:17 +00:00
|
|
|
Offset.QuadPart,
|
2012-03-28 18:39:21 +00:00
|
|
|
MmGetPfnForProcess(Process, Address));
|
|
|
|
if (Segment->FileObject)
|
|
|
|
{
|
|
|
|
DPRINTC("file %wZ\n", &Segment->FileObject->FileName);
|
|
|
|
}
|
|
|
|
Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
|
|
|
|
DPRINT("Entry %x\n", Entry);
|
|
|
|
if (Entry &&
|
|
|
|
!IS_SWAP_FROM_SSE(Entry) &&
|
|
|
|
PFN_FROM_SSE(Entry) == MmGetPfnForProcess(Process, Address)) {
|
|
|
|
|
|
|
|
MmSetPageEntrySectionSegment(Segment,
|
|
|
|
&Offset,
|
|
|
|
DIRTY_SSE(Entry));
|
|
|
|
}
|
|
|
|
MmSetPageProtect(Process, PAddress, PAGE_READWRITE);
|
|
|
|
MmSetDirtyPage(Process, PAddress);
|
|
|
|
MmUnlockSectionSegment(Segment);
|
|
|
|
DPRINT("Done\n");
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
2010-11-11 08:15:50 +00:00
|
|
|
#if 0
|
2012-03-28 18:39:21 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
DPRINT("Not supposed to be writable\n");
|
|
|
|
MmUnlockSectionSegment(Segment);
|
|
|
|
return STATUS_ACCESS_VIOLATION;
|
|
|
|
}
|
2010-11-11 08:15:50 +00:00
|
|
|
#endif
|
2012-03-28 18:39:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!Required->Page[0])
|
|
|
|
{
|
|
|
|
SWAPENTRY SwapEntry;
|
|
|
|
if (MmIsPageSwapEntry(Process, Address))
|
|
|
|
{
|
|
|
|
MmGetPageFileMapping(Process, Address, &SwapEntry);
|
|
|
|
MmUnlockSectionSegment(Segment);
|
|
|
|
if (SwapEntry == MM_WAIT_ENTRY)
|
|
|
|
return STATUS_SUCCESS + 1; // Wait ... somebody else is getting it right now
|
|
|
|
else
|
|
|
|
return STATUS_SUCCESS; // Nonwait swap entry ... handle elsewhere
|
|
|
|
}
|
2012-03-29 04:43:44 +00:00
|
|
|
/* Call out to acquire a page to copy to. We'll be re-called when
|
|
|
|
* the page has been allocated. */
|
2012-03-28 18:39:21 +00:00
|
|
|
Required->Page[1] = MmGetPfnForProcess(Process, Address);
|
|
|
|
Required->Consumer = MC_CACHE;
|
|
|
|
Required->Amount = 1;
|
|
|
|
Required->File = __FILE__;
|
|
|
|
Required->Line = __LINE__;
|
|
|
|
Required->DoAcquisition = MiGetOnePage;
|
|
|
|
MmCreatePageFileMapping(Process, Address, MM_WAIT_ENTRY);
|
|
|
|
MmUnlockSectionSegment(Segment);
|
|
|
|
return STATUS_MORE_PROCESSING_REQUIRED;
|
|
|
|
}
|
|
|
|
|
|
|
|
NewPage = Required->Page[0];
|
|
|
|
OldPage = Required->Page[1];
|
|
|
|
|
|
|
|
DPRINT("Allocated page %x\n", NewPage);
|
|
|
|
|
2012-12-19 23:49:13 +00:00
|
|
|
/* Unshare the old page */
|
|
|
|
MmDeleteRmap(OldPage, Process, PAddress);
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
|
2012-03-28 18:39:21 +00:00
|
|
|
/* Copy the old page */
|
|
|
|
DPRINT("Copying\n");
|
|
|
|
MiCopyPageToPage(NewPage, OldPage);
|
|
|
|
|
|
|
|
/* Set the PTE to point to the new page */
|
|
|
|
Status = MmCreateVirtualMapping(Process,
|
|
|
|
Address,
|
|
|
|
PAGE_READWRITE,
|
|
|
|
&NewPage,
|
|
|
|
1);
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("MmCreateVirtualMapping failed, not out of memory\n");
|
|
|
|
ASSERT(FALSE);
|
|
|
|
MmUnlockSectionSegment(Segment);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
MmInsertRmap(NewPage, Process, PAddress);
|
|
|
|
MmReleasePageMemoryConsumer(MC_CACHE, OldPage);
|
|
|
|
MmUnlockSectionSegment(Segment);
|
|
|
|
|
2013-02-16 17:37:17 +00:00
|
|
|
DPRINT("Address 0x%p\n", Address);
|
2012-03-28 18:39:21 +00:00
|
|
|
return STATUS_SUCCESS;
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
KEVENT MmWaitPageEvent;
|
|
|
|
|
|
|
|
typedef struct _WORK_QUEUE_WITH_CONTEXT
|
|
|
|
{
|
2012-03-28 18:39:21 +00:00
|
|
|
WORK_QUEUE_ITEM WorkItem;
|
|
|
|
PMMSUPPORT AddressSpace;
|
|
|
|
PMEMORY_AREA MemoryArea;
|
|
|
|
PMM_REQUIRED_RESOURCES Required;
|
|
|
|
NTSTATUS Status;
|
|
|
|
KEVENT Wait;
|
|
|
|
AcquireResource DoAcquisition;
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
} WORK_QUEUE_WITH_CONTEXT, *PWORK_QUEUE_WITH_CONTEXT;
|
|
|
|
|
2012-03-29 04:43:44 +00:00
|
|
|
/*
|
|
|
|
|
|
|
|
This is the work item used do blocking resource acquisition when a fault
|
|
|
|
handler returns STATUS_MORE_PROCESSING_REQUIRED. It's used to allow resource
|
|
|
|
acquisition to take place on a different stack, and outside of any locks used
|
|
|
|
by fault handling, making recursive fault handling possible when required.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
2012-12-19 23:49:13 +00:00
|
|
|
_Function_class_(WORKER_THREAD_ROUTINE)
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
VOID
|
|
|
|
NTAPI
|
2012-12-19 23:49:13 +00:00
|
|
|
MmpFaultWorker(PVOID Parameter)
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
{
|
2012-12-19 23:49:13 +00:00
|
|
|
PWORK_QUEUE_WITH_CONTEXT WorkItem = Parameter;
|
|
|
|
|
2012-03-28 18:39:21 +00:00
|
|
|
DPRINT("Calling work\n");
|
|
|
|
WorkItem->Status = WorkItem->Required->DoAcquisition(WorkItem->AddressSpace,
|
|
|
|
WorkItem->MemoryArea,
|
|
|
|
WorkItem->Required);
|
|
|
|
DPRINT("Status %x\n", WorkItem->Status);
|
|
|
|
KeSetEvent(&WorkItem->Wait, IO_NO_INCREMENT, FALSE);
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
}
|
|
|
|
|
2012-03-29 04:43:44 +00:00
|
|
|
/*
|
|
|
|
|
|
|
|
This code seperates the action of fault handling into an upper and lower
|
|
|
|
handler to allow the inner handler to optionally be called in work item
|
|
|
|
if the stack is getting too deep. My experiments show that the third
|
|
|
|
recursive page fault taken at PASSIVE_LEVEL must be shunted away to a
|
|
|
|
worker thread. In the ultimate form of this code, the primary fault handler
|
|
|
|
makes this decision by using a thread-local counter to detect a too-deep
|
|
|
|
fault stack and call the inner fault handler in a worker thread if required.
|
|
|
|
|
|
|
|
Note that faults are taken at passive level and have access to ordinary
|
|
|
|
driver entry points such as those that read and write files, and filesystems
|
|
|
|
should use paged structures whenever possible. This makes recursive faults
|
|
|
|
both a perfectly normal occurrance, and a worthwhile case to handle.
|
|
|
|
|
|
|
|
The code below will repeatedly call MiCowSectionPage as long as it returns
|
|
|
|
either STATUS_SUCCESS + 1 or STATUS_MORE_PROCESSING_REQUIRED. In the more
|
|
|
|
processing required case, we call out to a blocking resource acquisition
|
|
|
|
function and then recall the faut handler with the shared state represented
|
|
|
|
by the MM_REQUIRED_RESOURCES struct.
|
|
|
|
|
|
|
|
In the other case, we wait on the wait entry event and recall the handler.
|
|
|
|
Each time the wait entry event is signalled, one thread has removed an
|
|
|
|
MM_WAIT_ENTRY from a page table.
|
|
|
|
|
|
|
|
In the ultimate form of this code, there is a single system wide fault handler
|
|
|
|
for each of access fault and not present and each memory area contains a
|
2012-03-29 12:14:58 +00:00
|
|
|
function pointer that indicates the active fault handler. Since the mm code
|
2012-03-29 04:43:44 +00:00
|
|
|
in reactos is currently fragmented, I didn't bring this change to trunk.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
2012-03-28 18:39:21 +00:00
|
|
|
MmpSectionAccessFaultInner(KPROCESSOR_MODE Mode,
|
|
|
|
PMMSUPPORT AddressSpace,
|
|
|
|
ULONG_PTR Address,
|
|
|
|
BOOLEAN FromMdl,
|
|
|
|
PETHREAD Thread)
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
{
|
2012-03-28 18:39:21 +00:00
|
|
|
MEMORY_AREA* MemoryArea;
|
|
|
|
NTSTATUS Status;
|
|
|
|
BOOLEAN Locked = FromMdl;
|
|
|
|
MM_REQUIRED_RESOURCES Resources = { 0 };
|
|
|
|
WORK_QUEUE_WITH_CONTEXT Context;
|
|
|
|
|
|
|
|
RtlZeroMemory(&Context, sizeof(WORK_QUEUE_WITH_CONTEXT));
|
|
|
|
|
2013-02-16 17:37:17 +00:00
|
|
|
DPRINT("MmAccessFault(Mode %d, Address %Ix)\n", Mode, Address);
|
2012-03-28 18:39:21 +00:00
|
|
|
|
|
|
|
if (KeGetCurrentIrql() >= DISPATCH_LEVEL)
|
|
|
|
{
|
2013-02-16 17:37:17 +00:00
|
|
|
DPRINT1("Page fault at high IRQL was %u\n", KeGetCurrentIrql());
|
2012-03-28 18:39:21 +00:00
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Find the memory area for the faulting address */
|
|
|
|
if (Address >= (ULONG_PTR)MmSystemRangeStart)
|
|
|
|
{
|
|
|
|
/* Check permissions */
|
|
|
|
if (Mode != KernelMode)
|
|
|
|
{
|
2013-02-16 17:37:17 +00:00
|
|
|
DPRINT("MmAccessFault(Mode %d, Address %Ix)\n", Mode, Address);
|
2012-03-28 18:39:21 +00:00
|
|
|
return STATUS_ACCESS_VIOLATION;
|
|
|
|
}
|
|
|
|
AddressSpace = MmGetKernelAddressSpace();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
AddressSpace = &PsGetCurrentProcess()->Vm;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!FromMdl)
|
|
|
|
{
|
|
|
|
MmLockAddressSpace(AddressSpace);
|
|
|
|
}
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, (PVOID)Address);
|
|
|
|
if (MemoryArea == NULL ||
|
|
|
|
MemoryArea->DeleteInProgress)
|
|
|
|
{
|
|
|
|
if (!FromMdl)
|
|
|
|
{
|
|
|
|
MmUnlockAddressSpace(AddressSpace);
|
|
|
|
}
|
2013-02-16 17:37:17 +00:00
|
|
|
DPRINT("Address: %Ix\n", Address);
|
2012-03-28 18:39:21 +00:00
|
|
|
return STATUS_ACCESS_VIOLATION;
|
|
|
|
}
|
|
|
|
|
2013-02-16 17:37:17 +00:00
|
|
|
DPRINT("Type %x (%p -> %p)\n",
|
2012-03-28 18:39:21 +00:00
|
|
|
MemoryArea->Type,
|
2015-05-16 20:10:03 +00:00
|
|
|
MA_GetStartingAddress(MemoryArea),
|
2015-05-16 20:10:26 +00:00
|
|
|
MA_GetEndingAddress(MemoryArea));
|
2012-03-28 18:39:21 +00:00
|
|
|
|
|
|
|
Resources.DoAcquisition = NULL;
|
|
|
|
|
|
|
|
// Note: fault handlers are called with address space locked
|
|
|
|
// We return STATUS_MORE_PROCESSING_REQUIRED if anything is needed
|
|
|
|
Status = MiCowCacheSectionPage(AddressSpace,
|
|
|
|
MemoryArea,
|
|
|
|
(PVOID)Address,
|
|
|
|
Locked,
|
|
|
|
&Resources);
|
|
|
|
|
|
|
|
if (!FromMdl)
|
|
|
|
{
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
MmUnlockAddressSpace(AddressSpace);
|
2012-03-28 18:39:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (Status == STATUS_SUCCESS + 1)
|
|
|
|
{
|
|
|
|
/* Wait page ... */
|
2013-02-16 17:37:17 +00:00
|
|
|
DPRINT("Waiting for %Ix\n", Address);
|
2012-03-28 18:39:21 +00:00
|
|
|
MiWaitForPageEvent(MmGetAddressSpaceOwner(AddressSpace), Address);
|
2013-02-16 17:37:17 +00:00
|
|
|
DPRINT("Restarting fault %Ix\n", Address);
|
2012-03-28 18:39:21 +00:00
|
|
|
Status = STATUS_MM_RESTART_OPERATION;
|
|
|
|
}
|
|
|
|
else if (Status == STATUS_MM_RESTART_OPERATION)
|
|
|
|
{
|
|
|
|
/* Clean slate */
|
|
|
|
RtlZeroMemory(&Resources, sizeof(Resources));
|
|
|
|
}
|
|
|
|
else if (Status == STATUS_MORE_PROCESSING_REQUIRED)
|
|
|
|
{
|
|
|
|
if (Thread->ActiveFaultCount > 0)
|
|
|
|
{
|
2013-02-16 17:37:17 +00:00
|
|
|
DPRINT("Already fault handling ... going to work item (%Ix)\n",
|
2012-03-28 18:39:21 +00:00
|
|
|
Address);
|
|
|
|
Context.AddressSpace = AddressSpace;
|
|
|
|
Context.MemoryArea = MemoryArea;
|
|
|
|
Context.Required = &Resources;
|
|
|
|
KeInitializeEvent(&Context.Wait, NotificationEvent, FALSE);
|
|
|
|
|
|
|
|
ExInitializeWorkItem(&Context.WorkItem,
|
2012-12-19 23:49:13 +00:00
|
|
|
MmpFaultWorker,
|
2012-03-28 18:39:21 +00:00
|
|
|
&Context);
|
|
|
|
|
|
|
|
DPRINT("Queue work item\n");
|
|
|
|
ExQueueWorkItem(&Context.WorkItem, DelayedWorkQueue);
|
|
|
|
DPRINT("Wait\n");
|
|
|
|
KeWaitForSingleObject(&Context.Wait, 0, KernelMode, FALSE, NULL);
|
|
|
|
Status = Context.Status;
|
|
|
|
DPRINT("Status %x\n", Status);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Status = Resources.DoAcquisition(AddressSpace, MemoryArea, &Resources);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
Status = STATUS_MM_RESTART_OPERATION;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!FromMdl)
|
|
|
|
{
|
|
|
|
MmLockAddressSpace(AddressSpace);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (Status == STATUS_MM_RESTART_OPERATION);
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status) && MemoryArea->Type == 1)
|
|
|
|
{
|
2013-02-16 17:37:17 +00:00
|
|
|
DPRINT1("Completed page fault handling %Ix %x\n", Address, Status);
|
|
|
|
DPRINT1("Type %x (%p -> %p)\n",
|
2012-03-28 18:39:21 +00:00
|
|
|
MemoryArea->Type,
|
2015-05-16 20:10:03 +00:00
|
|
|
MA_GetStartingAddress(MemoryArea),
|
2015-05-16 20:10:26 +00:00
|
|
|
MA_GetEndingAddress(MemoryArea));
|
2012-03-28 18:39:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!FromMdl)
|
|
|
|
{
|
|
|
|
MmUnlockAddressSpace(AddressSpace);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status;
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
}
|
|
|
|
|
2012-03-29 04:43:44 +00:00
|
|
|
/*
|
|
|
|
|
2012-03-29 12:14:58 +00:00
|
|
|
This is the outer fault handler mentioned in the description of
|
2012-03-29 04:43:44 +00:00
|
|
|
MmpSectionAccsesFaultInner. It increments a fault depth count in the current
|
|
|
|
thread.
|
|
|
|
|
|
|
|
In the ultimate form of this code, the lower fault handler will optionally
|
|
|
|
use the count to keep the kernel stack from overflowing.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
2012-03-28 18:39:21 +00:00
|
|
|
MmAccessFaultCacheSection(KPROCESSOR_MODE Mode,
|
|
|
|
ULONG_PTR Address,
|
|
|
|
BOOLEAN FromMdl)
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
{
|
2012-03-28 18:39:21 +00:00
|
|
|
PETHREAD Thread;
|
|
|
|
PMMSUPPORT AddressSpace;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
2013-02-16 17:37:17 +00:00
|
|
|
DPRINT("MmpAccessFault(Mode %d, Address %Ix)\n", Mode, Address);
|
2012-03-28 18:39:21 +00:00
|
|
|
|
|
|
|
Thread = PsGetCurrentThread();
|
|
|
|
|
|
|
|
if (KeGetCurrentIrql() >= DISPATCH_LEVEL)
|
|
|
|
{
|
2013-02-16 17:37:17 +00:00
|
|
|
DPRINT1("Page fault at high IRQL %u, address %Ix\n",
|
2012-03-28 18:39:21 +00:00
|
|
|
KeGetCurrentIrql(),
|
|
|
|
Address);
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Find the memory area for the faulting address */
|
|
|
|
if (Address >= (ULONG_PTR)MmSystemRangeStart)
|
|
|
|
{
|
|
|
|
/* Check permissions */
|
|
|
|
if (Mode != KernelMode)
|
|
|
|
{
|
2013-02-16 17:37:17 +00:00
|
|
|
DPRINT1("Address: %p:%Ix\n", PsGetCurrentProcess(), Address);
|
2012-03-28 18:39:21 +00:00
|
|
|
return STATUS_ACCESS_VIOLATION;
|
|
|
|
}
|
|
|
|
AddressSpace = MmGetKernelAddressSpace();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
AddressSpace = &PsGetCurrentProcess()->Vm;
|
|
|
|
}
|
|
|
|
|
|
|
|
Thread->ActiveFaultCount++;
|
|
|
|
Status = MmpSectionAccessFaultInner(Mode,
|
|
|
|
AddressSpace,
|
|
|
|
Address,
|
|
|
|
FromMdl,
|
|
|
|
Thread);
|
|
|
|
Thread->ActiveFaultCount--;
|
|
|
|
|
|
|
|
return Status;
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
}
|
|
|
|
|
2012-03-29 04:43:44 +00:00
|
|
|
/*
|
|
|
|
|
|
|
|
As above, this code seperates the active part of fault handling from a carrier
|
|
|
|
that can use the thread's active fault count to determine whether a work item
|
|
|
|
is required. Also as above, this function repeatedly calls the active not
|
|
|
|
present fault handler until a clear success or failure is received, using a
|
|
|
|
return of STATUS_MORE_PROCESSING_REQUIRED or STATUS_SUCCESS + 1.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
2012-03-28 18:39:21 +00:00
|
|
|
MmNotPresentFaultCacheSectionInner(KPROCESSOR_MODE Mode,
|
|
|
|
PMMSUPPORT AddressSpace,
|
|
|
|
ULONG_PTR Address,
|
|
|
|
BOOLEAN FromMdl,
|
|
|
|
PETHREAD Thread)
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
{
|
2012-03-28 18:39:21 +00:00
|
|
|
BOOLEAN Locked = FromMdl;
|
|
|
|
PMEMORY_AREA MemoryArea;
|
|
|
|
MM_REQUIRED_RESOURCES Resources = { 0 };
|
|
|
|
WORK_QUEUE_WITH_CONTEXT Context;
|
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
|
[NEWCC]
A reintegration checkpoint for the NewCC branch, brought to you by Team NewCC.
Differences with current ReactOS trunk:
* A new memory area type, MEMORY_AREA_CACHE, is added, which represents a mapped region of a file. In NEWCC mode, user sections are MEMORY_AREA_CACHE type as well, and obey new semantics. In non-NEWCC mode, they aren't used.
* A way of claiming a page entry for a specific thread's work is added. Placing the special SWAPENTRY value MM_WAIT_ENTRY in a page table, or in a section page table should indicate that memory management code is intended to wait for another thread to make some status change before checking the state of the page entry again. In code that uses this convention, a return value of STATUS_SUCCESS + 1 is used to indicate that the caller should use the MiWaitForPageEvent macro to wait until somebody has change the state of a wait entry before checking again. This is a lighter weight mechanism than PAGEOPs.
* A way of asking the caller to perform some blocking operation without locks held is provided. This replaces some spaghettified code in which locks are repeatedly taken and broken by code that performs various blocking operations. Using this mechanism, it is possible to do a small amount of non-blocking work, fill in a request, then return STATUS_MORE_PROCESSING_REQUIRED to request that locks be dropped and the blocking operation be carried out. A MM_REQUIRED_RESOURCES structure is provided to consumers of this contract to use to accumulate state across many blocking operations. Several functions wrapping blocking operations are provided in ntoskrnl/cache/reqtools.c.
* Image section pages are no longer direct mapped. This is done to simplify consolidation of ownership of pages under the data section system. At a later time, it may be possible to make data pages directly available to image sections for the same file. This is likely the only direct performance impact this code makes on non-NEWCC mode.
RMAPs:
* A new type of RMAP entry is introduced, distinguished by RMAP_IS_SEGMENT(Address) of the rmap entry. This kind of entry contains a pointer to a section page table node in the Process pointer, which in turn links back to the MM_SECTION_SEGMENT it belongs to. Therefore, a page belonging only to a segment (that is, a segment page that isn't mapped) can exist and be evicted using the normal page eviction mechanism in balance.c. Each of the rmap function has been modified to deal with segment rmaps.
* The low 8 bits of the Address field in a segment rmap denote the entry number in the generic table node pointed to by Process that points to the page the rmap belongs to. By combining them, you can determine the file offset the page belongs to.
* In NEWCC mode, MmSharePageEntry/UnsharePageEntry are not used, and instead the page reference count is used to keep track of the number of mappings of a page, allowing the last reference expiring to allow the page to be recycled without much intervention. These are still used in non-NEWCC mode. One change has been made, the count fields have been narrowed by 1 bit to make room for a dirty bit in SSE entries, needed when a page is present but unmapped.
Section page tables:
* The section page tables are now implemented using RtlGenericTables. This enables a fairly compact representation of section page tables without having the existence of a section object imply 4k of fake PDEs. In addition, each node in the generic table has a wide file offset that is a multiple of 256 pages, or 1 megabyte total. Besides needing wide file offsets, the only other visible change caused by the switch to generic tables for section page tables is the need to lock the section segment before interacting with the section page table.
Eviction:
* Page eviction in cache sections is accomplished by MmpPageOutPhysicalAddress. In the case of a shared page, it tries to remove all mappings of the indicated page. If this process fails at any point, the page will simply be drawn back into the target address spaces. After succeeding at this, if TRUE has been accumulated into the page's dirty bit in the section page table, it is written back, and then permanently removed.
NewCC mode:
* NEWCC mode is introduced, which rewrites the file cache to a set of cache stripes actively mapped, along with unmapped section data.
* NewCC is more authentic in its interpretation of the external interface to the windows cache than the current cache manager, implementing each of the cache manager functions according to the documented interface with no preconceived ideas about how anything should be implemented internally. Cache stripes are implemented on top of section objects, using the same memory manager paths, and therefore economizing code and complexity. This replaces a rather complicated system in which pages can be owned by the cache manager and the memory manager simultaneously and they must cooperate in a fairly sophisticated way to manage them. Since they're quite interdependent in the current code, modifying either is very difficult. In NEWCC, they have a clear division of labor and thus can be worked on independently.
* Several third party filesystems that use the kernel Cc interface work properly using NEWCC, including matt wu's ext3 driver.
* In contrast with code that tries to make CcInitializeCacheMap and CcUninitializeCacheMap into a pair that supports reference counting, NEWCC lazily initializes the shared and private cache maps as needed and uses the presence of a PrivateCacheMap on at least one file pointing to the SharedCacheMap as an indication that the FILE_OBJECT reference in the SharedCacheMap should still be held. When the last PrivateCacheMap is discarded, that's the appropriate time to tear down caching for a specific file, as the SharedCacheMap data is allowed to be saved and reused. We honor this by making the SharedCacheMap into a depot for keeping track of the PrivateCacheMap objects associated with views of a file.
svn path=/trunk/; revision=55833
2012-02-23 12:03:06 +00:00
|
|
|
RtlZeroMemory(&Context, sizeof(WORK_QUEUE_WITH_CONTEXT));
|
|
|
|
|
2012-03-28 18:39:21 +00:00
|
|
|
if (!FromMdl)
|
|
|
|
{
|
|
|
|
MmLockAddressSpace(AddressSpace);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Call the memory area specific fault handler */
|
|
|
|
do
|
|
|
|
{
|
|
|
|
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, (PVOID)Address);
|
|
|
|
if (MemoryArea == NULL || MemoryArea->DeleteInProgress)
|
|
|
|
{
|
|
|
|
Status = STATUS_ACCESS_VIOLATION;
|
|
|
|
if (MemoryArea)
|
|
|
|
{
|
|
|
|
DPRINT1("Type %x DIP %x\n",
|
|
|
|
MemoryArea->Type,
|
|
|
|
MemoryArea->DeleteInProgress);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPRINT1("No memory area\n");
|
|
|
|
}
|
2013-02-16 17:37:17 +00:00
|
|
|
DPRINT1("Process %p, Address %Ix\n",
|
2012-03-28 18:39:21 +00:00
|
|
|
MmGetAddressSpaceOwner(AddressSpace),
|
|
|
|
Address);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-02-16 17:37:17 +00:00
|
|
|
DPRINTC("Type %x (%p -> %08Ix -> %p) in %p\n",
|
2012-03-28 18:39:21 +00:00
|
|
|
MemoryArea->Type,
|
2015-05-16 20:10:03 +00:00
|
|
|
MA_GetStartingAddress(MemoryArea),
|
2012-03-28 18:39:21 +00:00
|
|
|
Address,
|
2015-05-16 20:10:26 +00:00
|
|
|
MA_GetEndingAddress(MemoryArea),
|
2012-03-28 18:39:21 +00:00
|
|
|
PsGetCurrentThread());
|
|
|
|
|
|
|
|
Resources.DoAcquisition = NULL;
|
|
|
|
|
|
|
|
// Note: fault handlers are called with address space locked
|
|
|
|
// We return STATUS_MORE_PROCESSING_REQUIRED if anything is needed
|
|
|
|
|
|
|
|
Status = MmNotPresentFaultCachePage(AddressSpace,
|
|
|
|
MemoryArea,
|
|
|
|
(PVOID)Address,
|
|
|
|
Locked,
|
|
|
|
&Resources);
|
|
|
|
|
|
|
|
if (!FromMdl)
|
|
|
|
{
|
|
|
|
MmUnlockAddressSpace(AddressSpace);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Status == STATUS_SUCCESS)
|
|
|
|
{
|
|
|
|
; // Nothing
|
|
|
|
}
|
|
|
|
else if (Status == STATUS_SUCCESS + 1)
|
|
|
|
{
|
|
|
|
/* Wait page ... */
|
2013-02-16 17:37:17 +00:00
|
|
|
DPRINT("Waiting for %Ix\n", Address);
|
2012-03-28 18:39:21 +00:00
|
|
|
MiWaitForPageEvent(MmGetAddressSpaceOwner(AddressSpace), Address);
|
2013-02-16 17:37:17 +00:00
|
|
|
DPRINT("Done waiting for %Ix\n", Address);
|
2012-03-28 18:39:21 +00:00
|
|
|
Status = STATUS_MM_RESTART_OPERATION;
|
|
|
|
}
|
|
|
|
else if (Status == STATUS_MM_RESTART_OPERATION)
|
|
|
|
{
|
|
|
|
/* Clean slate */
|
|
|
|
DPRINT("Clear resource\n");
|
|
|
|
RtlZeroMemory(&Resources, sizeof(Resources));
|
|
|
|
}
|
|
|
|
else if (Status == STATUS_MORE_PROCESSING_REQUIRED)
|
|
|
|
{
|
|
|
|
if (Thread->ActiveFaultCount > 2)
|
|
|
|
{
|
2013-02-16 17:37:17 +00:00
|
|
|
DPRINTC("Already fault handling ... going to work item (%Ix)\n", Address);
|
2012-03-28 18:39:21 +00:00
|
|
|
Context.AddressSpace = AddressSpace;
|
|
|
|
Context.MemoryArea = MemoryArea;
|
|
|
|
Context.Required = &Resources;
|
|
|
|
KeInitializeEvent(&Context.Wait, NotificationEvent, FALSE);
|
|
|
|
|
|
|
|
ExInitializeWorkItem(&Context.WorkItem,
|
|
|
|
(PWORKER_THREAD_ROUTINE)MmpFaultWorker,
|
|
|
|
&Context);
|
|
|
|
|
|
|
|
DPRINT("Queue work item\n");
|
|
|
|
ExQueueWorkItem(&Context.WorkItem, DelayedWorkQueue);
|
|
|
|
DPRINT("Wait\n");
|
|
|
|
KeWaitForSingleObject(&Context.Wait, 0, KernelMode, FALSE, NULL);
|
|
|
|
Status = Context.Status;
|
|
|
|
DPRINTC("Status %x\n", Status);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-02-16 17:37:17 +00:00
|
|
|
DPRINT("DoAcquisition %p\n", Resources.DoAcquisition);
|
2012-03-28 18:39:21 +00:00
|
|
|
|
|
|
|
Status = Resources.DoAcquisition(AddressSpace,
|
|
|
|
MemoryArea,
|
|
|
|
&Resources);
|
|
|
|
|
2013-02-16 17:37:17 +00:00
|
|
|
DPRINT("DoAcquisition %p -> %x\n",
|
2012-03-28 18:39:21 +00:00
|
|
|
Resources.DoAcquisition,
|
|
|
|
Status);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
Status = STATUS_MM_RESTART_OPERATION;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
ASSERT(FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!FromMdl)
|
|
|
|
{
|
|
|
|
MmLockAddressSpace(AddressSpace);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (Status == STATUS_MM_RESTART_OPERATION);
|
|
|
|
|
2013-02-16 17:37:17 +00:00
|
|
|
DPRINTC("Completed page fault handling: %p:%Ix %x\n",
|
2012-03-28 18:39:21 +00:00
|
|
|
MmGetAddressSpaceOwner(AddressSpace),
|
|
|
|
Address,
|
|
|
|
Status);
|
|
|
|
|
|
|
|
if (!FromMdl)
|
|
|
|
{
|
|
|
|
MmUnlockAddressSpace(AddressSpace);
|
|
|
|
}
|
|
|
|
|
|
|
|
MiSetPageEvent(MmGetAddressSpaceOwner(AddressSpace), Address);
|
|
|
|
DPRINT("Done %x\n", Status);
|
|
|
|
|
|
|
|
return Status;
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
}
|
|
|
|
|
2012-03-29 04:43:44 +00:00
|
|
|
/*
|
|
|
|
|
|
|
|
Call the inner not present fault handler, keeping track of the fault count.
|
|
|
|
In the ultimate form of this code, optionally use a worker thread the handle
|
|
|
|
the fault in order to sidestep stack overflow in the multiple fault case.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
2012-03-28 18:39:21 +00:00
|
|
|
MmNotPresentFaultCacheSection(KPROCESSOR_MODE Mode,
|
|
|
|
ULONG_PTR Address,
|
|
|
|
BOOLEAN FromMdl)
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
{
|
2012-03-28 18:39:21 +00:00
|
|
|
PETHREAD Thread;
|
|
|
|
PMMSUPPORT AddressSpace;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
Address &= ~(PAGE_SIZE - 1);
|
2013-02-16 17:37:17 +00:00
|
|
|
DPRINT("MmNotPresentFault(Mode %d, Address %Ix)\n", Mode, Address);
|
2012-03-28 18:39:21 +00:00
|
|
|
|
|
|
|
Thread = PsGetCurrentThread();
|
|
|
|
|
|
|
|
if (KeGetCurrentIrql() >= DISPATCH_LEVEL)
|
|
|
|
{
|
2013-02-16 17:37:17 +00:00
|
|
|
DPRINT1("Page fault at high IRQL %u, address %Ix\n",
|
2012-03-28 18:39:21 +00:00
|
|
|
KeGetCurrentIrql(),
|
|
|
|
Address);
|
|
|
|
|
|
|
|
ASSERT(FALSE);
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Find the memory area for the faulting address */
|
|
|
|
if (Address >= (ULONG_PTR)MmSystemRangeStart)
|
|
|
|
{
|
|
|
|
/* Check permissions */
|
|
|
|
if (Mode != KernelMode)
|
|
|
|
{
|
|
|
|
DPRINTC("Address: %x\n", Address);
|
|
|
|
return STATUS_ACCESS_VIOLATION;
|
|
|
|
}
|
|
|
|
AddressSpace = MmGetKernelAddressSpace();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
AddressSpace = &PsGetCurrentProcess()->Vm;
|
|
|
|
}
|
|
|
|
|
|
|
|
Thread->ActiveFaultCount++;
|
|
|
|
Status = MmNotPresentFaultCacheSectionInner(Mode,
|
|
|
|
AddressSpace,
|
|
|
|
Address,
|
|
|
|
FromMdl,
|
|
|
|
Thread);
|
|
|
|
Thread->ActiveFaultCount--;
|
|
|
|
|
|
|
|
ASSERT(Status != STATUS_UNSUCCESSFUL);
|
|
|
|
ASSERT(Status != STATUS_INVALID_PARAMETER);
|
2013-02-16 17:37:17 +00:00
|
|
|
DPRINT("MmAccessFault %p:%Ix -> %x\n",
|
2012-03-28 18:39:21 +00:00
|
|
|
MmGetAddressSpaceOwner(AddressSpace),
|
|
|
|
Address,
|
|
|
|
Status);
|
|
|
|
|
|
|
|
return Status;
|
[CACHE]
The cache manager rewrite I started years ago has finally appeared in
ReactOS' trunk and although at this point it's not quite perfectly
integrated, it's enough to boot up the bootcd or livecd. To check out
the more mature original, check out arty-newcc-reactos, branch
arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit
to not give up on it, and was able to reach out and be an advocate
when i really wasn't able to. Others agree that the time has come to
begin removing the old cache manager. I expect the remaining problems
in the version going to trunk will be taken care of relatively
quickly.
The motivation for this effort lies in the particularly hairy
relationship between ReactOS' cache manager and data sections. This
code completely removes page sharing between cache manager and section
and reimagines cache manager as being a facility layered on the memory
manager, not really caring about individual pages, but simply managing
data section objects where caching might occur.
It took me about 2 years to do the first pass of this rewrite and most
of this year to fix some lingering issues, properly implement demand
paging in ReactOS (code which didn't come with this patch in a
recognizable form), and finish getting the PrivateCacheMap and
SharedCacheMap relationship correct.
Currently, the new ntoskrnl/cache directory contains an own
implementation of data file sections. After things have settled down,
we can begin to deprecate and remove the parts of ReactOS' section
implementation that depend on a close relationship with cache
manager. Eventually, I think that the extra code added to
ntoskrnl/cache/section will be removed and ReactOS' own sections will
replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache
path.
Note also, that this makes all cache manager (and new section parts)
use wide file offsets. If my section code were to take over other
parts of the ReactOS memory manager, they would also benefit from
these improvements.
I invite anyone who wants to to peek at this code and fix whatever
bugs can be found.
svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
|
|
|
}
|