[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/swapout.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
|
|
|
/*
|
|
|
|
|
|
|
|
This file implements page out infrastructure for cache type sections. This
|
|
|
|
is implemented a little differently from the legacy mm because mapping in an
|
|
|
|
address space and membership in a segment are considered separate.
|
|
|
|
|
|
|
|
The general strategy here is to try to remove all mappings as gently as
|
|
|
|
possible, then to remove the page entry from the section itself as a final
|
|
|
|
step. If at any time during the page out operation, the page is mapped in
|
|
|
|
a new address space by a competing thread, the operation will abort before
|
|
|
|
the segment page is finally removed, and the page will be naturally faulted
|
|
|
|
back into any address spaces required in the normal way.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
[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>
|
|
|
|
|
|
|
|
#define DPRINTC DPRINT
|
|
|
|
|
|
|
|
extern KEVENT MmWaitPageEvent;
|
|
|
|
extern FAST_MUTEX RmapListLock;
|
2012-02-28 09:30:53 +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
|
|
|
|
[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
|
|
|
FAST_MUTEX MiGlobalPageOperation;
|
[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
|
|
|
/*
|
|
|
|
|
|
|
|
MmWithdrawSectionPage removes a page entry from the section segment, replacing
|
|
|
|
it with a wait entry. The caller must replace the wait entry with a 0, when
|
2012-03-29 12:14:58 +00:00
|
|
|
any required writing is done. The wait entry must remain until the page is
|
2012-03-29 04:43:44 +00:00
|
|
|
written to protect against cases where a fault brings a stale copy of the page
|
|
|
|
back before writing is complete.
|
|
|
|
|
|
|
|
*/
|
[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
|
|
|
PFN_NUMBER
|
|
|
|
NTAPI
|
2012-03-28 18:39:21 +00:00
|
|
|
MmWithdrawSectionPage(PMM_SECTION_SEGMENT Segment,
|
|
|
|
PLARGE_INTEGER FileOffset,
|
|
|
|
BOOLEAN *Dirty)
|
[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 19:41:40 +00:00
|
|
|
ULONG_PTR Entry;
|
2012-03-28 18:39:21 +00:00
|
|
|
|
2013-08-31 16:02:13 +00:00
|
|
|
DPRINT("MmWithdrawSectionPage(%p,%08x%08x,%p)\n",
|
2012-03-28 18:39:21 +00:00
|
|
|
Segment,
|
|
|
|
FileOffset->HighPart,
|
|
|
|
FileOffset->LowPart,
|
|
|
|
Dirty);
|
|
|
|
|
|
|
|
MmLockSectionSegment(Segment);
|
|
|
|
Entry = MmGetPageEntrySectionSegment(Segment, FileOffset);
|
|
|
|
|
|
|
|
*Dirty = !!IS_DIRTY_SSE(Entry);
|
|
|
|
|
|
|
|
DPRINT("Withdraw %x (%x) of %wZ\n",
|
|
|
|
FileOffset->LowPart,
|
|
|
|
Entry,
|
|
|
|
Segment->FileObject ? &Segment->FileObject->FileName : NULL);
|
|
|
|
|
|
|
|
if (!Entry)
|
|
|
|
{
|
|
|
|
DPRINT("Stoeled!\n");
|
|
|
|
MmUnlockSectionSegment(Segment);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else if (MM_IS_WAIT_PTE(Entry))
|
|
|
|
{
|
|
|
|
DPRINT("WAIT\n");
|
|
|
|
MmUnlockSectionSegment(Segment);
|
|
|
|
return MM_WAIT_ENTRY;
|
|
|
|
}
|
|
|
|
else if (Entry && !IS_SWAP_FROM_SSE(Entry))
|
|
|
|
{
|
|
|
|
DPRINT("Page %x\n", PFN_FROM_SSE(Entry));
|
|
|
|
|
|
|
|
*Dirty |= (Entry & 2);
|
|
|
|
|
|
|
|
MmSetPageEntrySectionSegment(Segment,
|
|
|
|
FileOffset,
|
|
|
|
MAKE_SWAP_SSE(MM_WAIT_ENTRY));
|
|
|
|
|
|
|
|
MmUnlockSectionSegment(Segment);
|
|
|
|
return PFN_FROM_SSE(Entry);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-08-31 16:02:13 +00:00
|
|
|
DPRINT1("SWAP ENTRY?! (%p:%08x%08x)\n",
|
2012-03-28 18:39:21 +00:00
|
|
|
Segment,
|
|
|
|
FileOffset->HighPart,
|
|
|
|
FileOffset->LowPart);
|
|
|
|
|
|
|
|
ASSERT(FALSE);
|
|
|
|
MmUnlockSectionSegment(Segment);
|
|
|
|
return 0;
|
|
|
|
}
|
[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 determines whether the segment holds the very last reference to
|
2012-03-29 12:14:58 +00:00
|
|
|
the page being considered and if so, writes it back or discards it as
|
2012-03-29 04:43:44 +00:00
|
|
|
approriate. One small niggle here is that we might be holding the last
|
|
|
|
reference to the section segment associated with this page. That happens
|
|
|
|
when the segment is destroyed at the same time that an active swap operation
|
|
|
|
is occurring, and all maps were already withdrawn. In that case, it's our
|
|
|
|
responsiblity for finalizing the segment.
|
|
|
|
|
|
|
|
Note that in the current code, WriteZero is always TRUE because the section
|
|
|
|
always backs a file. In the ultimate form of this code, it also writes back
|
|
|
|
pages without necessarily evicting them. In reactos' trunk, this is vestigal.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
[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
|
|
|
MmFinalizeSectionPageOut(PMM_SECTION_SEGMENT Segment,
|
|
|
|
PLARGE_INTEGER FileOffset,
|
|
|
|
PFN_NUMBER Page,
|
|
|
|
BOOLEAN Dirty)
|
[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 = STATUS_SUCCESS;
|
|
|
|
BOOLEAN WriteZero = FALSE, WritePage = FALSE;
|
|
|
|
SWAPENTRY Swap = MmGetSavedSwapEntryPage(Page);
|
[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-05 19:15:15 +00:00
|
|
|
/* Bail early if the reference count isn't where we need it */
|
2021-05-20 09:48:02 +00:00
|
|
|
if (MmGetReferenceCountPageWithoutLock(Page) != 1)
|
2012-03-05 19:15:15 +00:00
|
|
|
{
|
2013-08-31 16:02:13 +00:00
|
|
|
DPRINT1("Cannot page out locked page %x with ref count %lu\n",
|
2012-03-28 18:39:21 +00:00
|
|
|
Page,
|
2021-05-20 09:48:02 +00:00
|
|
|
MmGetReferenceCountPageWithoutLock(Page));
|
2012-03-05 19:15:15 +00:00
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
2012-03-28 18:39:21 +00:00
|
|
|
MmLockSectionSegment(Segment);
|
|
|
|
(void)InterlockedIncrementUL(&Segment->ReferenceCount);
|
|
|
|
|
|
|
|
if (Dirty)
|
|
|
|
{
|
2013-08-31 16:02:13 +00:00
|
|
|
DPRINT("Finalize (dirty) Segment %p Page %x\n", Segment, Page);
|
|
|
|
DPRINT("Segment->FileObject %p\n", Segment->FileObject);
|
2012-03-28 18:39:21 +00:00
|
|
|
DPRINT("Segment->Flags %x\n", Segment->Flags);
|
|
|
|
|
|
|
|
WriteZero = TRUE;
|
|
|
|
WritePage = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
WriteZero = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
DPRINT("Status %x\n", Status);
|
|
|
|
|
|
|
|
MmUnlockSectionSegment(Segment);
|
|
|
|
|
|
|
|
if (WritePage)
|
|
|
|
{
|
2013-08-31 16:02:13 +00:00
|
|
|
DPRINT("MiWriteBackPage(Segment %p FileObject %p Offset %x)\n",
|
2012-03-28 18:39:21 +00:00
|
|
|
Segment,
|
|
|
|
Segment->FileObject,
|
|
|
|
FileOffset->LowPart);
|
|
|
|
|
|
|
|
Status = MiWriteBackPage(Segment->FileObject,
|
|
|
|
FileOffset,
|
|
|
|
PAGE_SIZE,
|
|
|
|
Page);
|
|
|
|
}
|
|
|
|
|
|
|
|
MmLockSectionSegment(Segment);
|
|
|
|
|
|
|
|
if (WriteZero && NT_SUCCESS(Status))
|
|
|
|
{
|
2013-08-31 16:02:13 +00:00
|
|
|
DPRINT("Setting page entry in segment %p:%x to swap %x\n",
|
2012-03-28 18:39:21 +00:00
|
|
|
Segment,
|
|
|
|
FileOffset->LowPart,
|
|
|
|
Swap);
|
|
|
|
|
|
|
|
MmSetPageEntrySectionSegment(Segment,
|
|
|
|
FileOffset,
|
|
|
|
Swap ? MAKE_SWAP_SSE(Swap) : 0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-08-31 16:02:13 +00:00
|
|
|
DPRINT("Setting page entry in segment %p:%x to page %x\n",
|
2012-03-28 18:39:21 +00:00
|
|
|
Segment,
|
|
|
|
FileOffset->LowPart,
|
|
|
|
Page);
|
|
|
|
|
|
|
|
MmSetPageEntrySectionSegment(Segment,
|
|
|
|
FileOffset,
|
|
|
|
Page ? (Dirty ? DIRTY_SSE(MAKE_PFN_SSE(Page)) : MAKE_PFN_SSE(Page)) : 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT("Removing page %x for real\n", Page);
|
|
|
|
MmSetSavedSwapEntryPage(Page, 0);
|
|
|
|
MmReleasePageMemoryConsumer(MC_CACHE, Page);
|
|
|
|
}
|
|
|
|
|
|
|
|
MmUnlockSectionSegment(Segment);
|
|
|
|
|
|
|
|
if (InterlockedDecrementUL(&Segment->ReferenceCount) == 0)
|
|
|
|
{
|
|
|
|
MmFinalizeSegment(Segment);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Note: Writing may evict the segment... Nothing is guaranteed from here down */
|
2018-01-01 14:24:05 +00:00
|
|
|
MiSetPageEvent(Segment, (ULONG_PTR)FileOffset->QuadPart);
|
2012-03-28 18:39:21 +00:00
|
|
|
|
|
|
|
DPRINT("Status %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
|
|
|
/*
|
|
|
|
|
|
|
|
The slightly misnamed MmPageOutCacheSection removes a page from an address
|
|
|
|
space in the manner of fault handlers found in fault.c. In the ultimate form
|
|
|
|
of the code, this is one of the function pointers stored in a memory area
|
2012-03-29 12:14:58 +00:00
|
|
|
to control how pages in that memory area are managed.
|
2012-03-29 04:43:44 +00:00
|
|
|
|
|
|
|
Also misleading is the call to MmReleasePageMemoryConsumer, which releases
|
|
|
|
the reference held by this address space only. After all address spaces
|
|
|
|
have had MmPageOutCacheSection succeed on them for the indicated page,
|
|
|
|
then paging out of a cache page can continue.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
[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
|
|
|
MmPageOutCacheSection(PMMSUPPORT AddressSpace,
|
|
|
|
MEMORY_AREA* MemoryArea,
|
|
|
|
PVOID Address,
|
|
|
|
PBOOLEAN Dirty,
|
|
|
|
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 19:41:40 +00:00
|
|
|
ULONG_PTR Entry;
|
2012-02-24 11:33:23 +00:00
|
|
|
PFN_NUMBER OurPage;
|
2012-03-28 18:39:21 +00:00
|
|
|
PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
|
|
|
|
LARGE_INTEGER TotalOffset;
|
|
|
|
PMM_SECTION_SEGMENT Segment;
|
|
|
|
PVOID PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
|
[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
|
|
|
|
2015-05-16 20:10:03 +00:00
|
|
|
TotalOffset.QuadPart = (ULONG_PTR)PAddress -
|
|
|
|
MA_GetStartingAddress(MemoryArea) +
|
2012-03-28 18:39:21 +00:00
|
|
|
MemoryArea->Data.SectionData.ViewOffset.QuadPart;
|
[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
|
|
|
Segment = MemoryArea->Data.SectionData.Segment;
|
[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
|
|
|
MmLockSectionSegment(Segment);
|
|
|
|
ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
|
[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
|
|
|
Entry = MmGetPageEntrySectionSegment(Segment, &TotalOffset);
|
2013-06-02 19:04:02 +00:00
|
|
|
DBG_UNREFERENCED_LOCAL_VARIABLE(Entry);
|
[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
|
|
|
if (MmIsPageSwapEntry(Process, PAddress))
|
|
|
|
{
|
2012-03-05 02:20:22 +00:00
|
|
|
SWAPENTRY SwapEntry;
|
|
|
|
MmGetPageFileMapping(Process, PAddress, &SwapEntry);
|
2012-03-28 18:39:21 +00:00
|
|
|
MmUnlockSectionSegment(Segment);
|
|
|
|
return SwapEntry == MM_WAIT_ENTRY ? STATUS_SUCCESS + 1 : STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
2012-03-04 23:45:16 +00:00
|
|
|
|
2012-02-24 11:33:23 +00:00
|
|
|
MmDeleteRmap(Required->Page[0], Process, Address);
|
2014-10-05 07:16:01 +00:00
|
|
|
MmDeleteVirtualMapping(Process, Address, Dirty, &OurPage);
|
2012-02-24 11:33:23 +00:00
|
|
|
ASSERT(OurPage == Required->Page[0]);
|
[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
|
|
|
/* Note: this releases the reference held by this address space only. */
|
2012-03-28 18:39:21 +00:00
|
|
|
MmReleasePageMemoryConsumer(MC_CACHE, Required->Page[0]);
|
2012-02-28 09:30:53 +00:00
|
|
|
|
2012-03-28 18:39:21 +00:00
|
|
|
MmUnlockSectionSegment(Segment);
|
|
|
|
MiSetPageEvent(Process, Address);
|
|
|
|
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 12:14:58 +00:00
|
|
|
/*
|
2012-03-29 04:43:44 +00:00
|
|
|
|
|
|
|
This function is called by rmap when spare pages are needed by the blancer.
|
|
|
|
It attempts first to release the page from every address space in which it
|
|
|
|
appears, and, after a final check that no competing thread has mapped the
|
|
|
|
page again, uses MmFinalizeSectionPageOut to completely evict the page. If
|
|
|
|
that's successful, then a suitable non-page map will be left in the segment
|
|
|
|
page table, otherwise, the original page is replaced in the section page
|
|
|
|
map. Failure may result from a variety of conditions, but always leaves
|
|
|
|
the page mapped.
|
|
|
|
|
|
|
|
This code is like the other fault handlers, in that MmPageOutCacheSection has
|
|
|
|
the option of returning either STATUS_SUCCESS + 1 to wait for a wait entry
|
2012-03-29 12:14:58 +00:00
|
|
|
to disppear or to use the blocking callout facility by returning
|
2012-03-29 04:43:44 +00:00
|
|
|
STATUS_MORE_PROCESSING_REQUIRED and placing a pointer to a function from
|
|
|
|
reqtools.c in the MM_REQUIRED_RESOURCES struct.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
[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
|
|
|
|
MmpPageOutPhysicalAddress(PFN_NUMBER Page)
|
|
|
|
{
|
2012-03-28 18:39:21 +00:00
|
|
|
BOOLEAN ProcRef = FALSE, PageDirty;
|
|
|
|
PFN_NUMBER SectionPage = 0;
|
|
|
|
PMM_RMAP_ENTRY entry;
|
|
|
|
PMM_SECTION_SEGMENT Segment = NULL;
|
|
|
|
LARGE_INTEGER FileOffset;
|
|
|
|
PMEMORY_AREA MemoryArea;
|
[NTOSKRNL]
Coverity code defects fixes :
- Cache: CID 701441
- Config: CIDs 716570, 716669, 716760
- Dbgk: Kdbg: CIDs 716571, 515128/9, 500432
- Ex: CIDs 500156/7, 515122, 716200/67, 701301, 514669
- Fsrtl: Fstub: CIDs 701341/2, 701288, 716770, 701302, and CIDs 716576/7/8 + 514636 + 716805 thanks to Thomas Faber
- Io: CIDs 514576, 514643, 514672/3, 716203, 716269, 716581, 716591, 716713
- Ke: CIDs 515125, 716592
- Ps: CIDs 716603/4, 701422
- Ob: Po: CIDs 514671/680, 701419/420/421, 716763, 716601/2
All the details are given in the different bug reports.
CORE-6677 CORE-6679 CORE-6680 CORE-6683 CORE-6686 CORE-6692 CORE-6693 CORE-6694 CORE-6695 CORE-6696 #comment Committed in rev.57400 #resolve #close
svn path=/trunk/; revision=57400
2012-09-27 17:16:31 +00:00
|
|
|
PMMSUPPORT AddressSpace = NULL;
|
2012-03-28 18:39:21 +00:00
|
|
|
BOOLEAN Dirty = FALSE;
|
|
|
|
PVOID Address = NULL;
|
|
|
|
PEPROCESS Process = NULL;
|
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
|
|
MM_REQUIRED_RESOURCES Resources = { 0 };
|
|
|
|
|
2021-05-20 09:48:02 +00:00
|
|
|
DPRINTC("Page out %x (ref ct %x)\n", Page, MmGetReferenceCountPageWithoutLock(Page));
|
2012-03-28 18:39:21 +00:00
|
|
|
|
|
|
|
ExAcquireFastMutex(&MiGlobalPageOperation);
|
|
|
|
if ((Segment = MmGetSectionAssociation(Page, &FileOffset)))
|
|
|
|
{
|
2013-08-31 16:02:13 +00:00
|
|
|
DPRINTC("Withdrawing page (%x) %p:%x\n",
|
2012-03-28 18:39:21 +00:00
|
|
|
Page,
|
|
|
|
Segment,
|
|
|
|
FileOffset.LowPart);
|
|
|
|
|
|
|
|
SectionPage = MmWithdrawSectionPage(Segment, &FileOffset, &Dirty);
|
|
|
|
DPRINTC("SectionPage %x\n", SectionPage);
|
|
|
|
|
|
|
|
if (SectionPage == MM_WAIT_ENTRY || SectionPage == 0)
|
|
|
|
{
|
|
|
|
DPRINT1("In progress page out %x\n", SectionPage);
|
|
|
|
ExReleaseFastMutex(&MiGlobalPageOperation);
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ASSERT(SectionPage == Page);
|
|
|
|
}
|
|
|
|
Resources.State = Dirty ? 1 : 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPRINT("No segment association for %x\n", Page);
|
|
|
|
}
|
|
|
|
|
|
|
|
Dirty = MmIsDirtyPageRmap(Page);
|
|
|
|
|
|
|
|
DPRINTC("Trying to unmap all instances of %x\n", Page);
|
|
|
|
ExAcquireFastMutex(&RmapListLock);
|
|
|
|
entry = MmGetRmapListHeadPage(Page);
|
|
|
|
|
|
|
|
// Entry and Segment might be null here in the case that the page
|
|
|
|
// is new and is in the process of being swapped in
|
|
|
|
if (!entry && !Segment)
|
|
|
|
{
|
|
|
|
Status = STATUS_UNSUCCESSFUL;
|
|
|
|
DPRINT1("Page %x is in transit\n", Page);
|
|
|
|
ExReleaseFastMutex(&RmapListLock);
|
|
|
|
goto bail;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (entry != NULL && NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
Process = entry->Process;
|
|
|
|
Address = entry->Address;
|
|
|
|
|
2013-08-31 16:02:13 +00:00
|
|
|
DPRINTC("Process %p Address %p Page %x\n", Process, Address, Page);
|
2012-03-28 18:39:21 +00:00
|
|
|
|
[NTOSKRNL]
Coverity code defects fixes :
- Cache: CID 701441
- Config: CIDs 716570, 716669, 716760
- Dbgk: Kdbg: CIDs 716571, 515128/9, 500432
- Ex: CIDs 500156/7, 515122, 716200/67, 701301, 514669
- Fsrtl: Fstub: CIDs 701341/2, 701288, 716770, 701302, and CIDs 716576/7/8 + 514636 + 716805 thanks to Thomas Faber
- Io: CIDs 514576, 514643, 514672/3, 716203, 716269, 716581, 716591, 716713
- Ke: CIDs 515125, 716592
- Ps: CIDs 716603/4, 701422
- Ob: Po: CIDs 514671/680, 701419/420/421, 716763, 716601/2
All the details are given in the different bug reports.
CORE-6677 CORE-6679 CORE-6680 CORE-6683 CORE-6686 CORE-6692 CORE-6693 CORE-6694 CORE-6695 CORE-6696 #comment Committed in rev.57400 #resolve #close
svn path=/trunk/; revision=57400
2012-09-27 17:16:31 +00:00
|
|
|
if (RMAP_IS_SEGMENT(Address))
|
|
|
|
{
|
2012-03-28 18:39:21 +00:00
|
|
|
entry = entry->Next;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Process && Address < MmSystemRangeStart)
|
|
|
|
{
|
|
|
|
/* Make sure we don't try to page out part of an exiting process */
|
|
|
|
if (PspIsProcessExiting(Process))
|
|
|
|
{
|
|
|
|
DPRINT("bail\n");
|
|
|
|
ExReleaseFastMutex(&RmapListLock);
|
|
|
|
goto bail;
|
|
|
|
}
|
2012-03-28 21:09:03 +00:00
|
|
|
ObReferenceObject(Process);
|
2012-03-28 18:39:21 +00:00
|
|
|
ProcRef = TRUE;
|
|
|
|
AddressSpace = &Process->Vm;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
AddressSpace = MmGetKernelAddressSpace();
|
|
|
|
}
|
|
|
|
ExReleaseFastMutex(&RmapListLock);
|
|
|
|
|
|
|
|
RtlZeroMemory(&Resources, sizeof(Resources));
|
|
|
|
|
|
|
|
if ((((ULONG_PTR)Address) & 0xFFF) != 0)
|
|
|
|
{
|
|
|
|
KeBugCheck(MEMORY_MANAGEMENT);
|
|
|
|
}
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
[NTOSKRNL]
Coverity code defects fixes :
- Cache: CID 701441
- Config: CIDs 716570, 716669, 716760
- Dbgk: Kdbg: CIDs 716571, 515128/9, 500432
- Ex: CIDs 500156/7, 515122, 716200/67, 701301, 514669
- Fsrtl: Fstub: CIDs 701341/2, 701288, 716770, 701302, and CIDs 716576/7/8 + 514636 + 716805 thanks to Thomas Faber
- Io: CIDs 514576, 514643, 514672/3, 716203, 716269, 716581, 716591, 716713
- Ke: CIDs 515125, 716592
- Ps: CIDs 716603/4, 701422
- Ob: Po: CIDs 514671/680, 701419/420/421, 716763, 716601/2
All the details are given in the different bug reports.
CORE-6677 CORE-6679 CORE-6680 CORE-6683 CORE-6686 CORE-6692 CORE-6693 CORE-6694 CORE-6695 CORE-6696 #comment Committed in rev.57400 #resolve #close
svn path=/trunk/; revision=57400
2012-09-27 17:16:31 +00:00
|
|
|
MmLockAddressSpace(AddressSpace);
|
|
|
|
|
2012-03-28 18:39:21 +00:00
|
|
|
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, Address);
|
|
|
|
if (MemoryArea == NULL || MemoryArea->DeleteInProgress)
|
|
|
|
{
|
|
|
|
Status = STATUS_UNSUCCESSFUL;
|
|
|
|
MmUnlockAddressSpace(AddressSpace);
|
|
|
|
DPRINTC("bail\n");
|
|
|
|
goto bail;
|
|
|
|
}
|
|
|
|
|
2013-08-31 16:02:13 +00:00
|
|
|
DPRINTC("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;
|
|
|
|
Resources.Page[0] = Page;
|
|
|
|
|
|
|
|
ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
|
|
|
|
|
2013-08-31 16:02:13 +00:00
|
|
|
DPRINT("%p:%p, page %x %x\n",
|
2012-03-28 18:39:21 +00:00
|
|
|
Process,
|
|
|
|
Address,
|
|
|
|
Page,
|
|
|
|
Resources.Page[0]);
|
|
|
|
|
|
|
|
PageDirty = FALSE;
|
|
|
|
|
|
|
|
Status = MmPageOutCacheSection(AddressSpace,
|
|
|
|
MemoryArea,
|
|
|
|
Address,
|
|
|
|
&PageDirty,
|
|
|
|
&Resources);
|
|
|
|
|
|
|
|
Dirty |= PageDirty;
|
|
|
|
DPRINT("%x\n", Status);
|
|
|
|
|
|
|
|
ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
|
|
|
|
|
|
|
|
MmUnlockAddressSpace(AddressSpace);
|
|
|
|
|
|
|
|
if (Status == STATUS_SUCCESS + 1)
|
|
|
|
{
|
|
|
|
// Wait page ... the other guy has it, so we'll just fail for now
|
|
|
|
DPRINT1("Wait entry ... can't continue\n");
|
|
|
|
Status = STATUS_UNSUCCESSFUL;
|
|
|
|
goto bail;
|
|
|
|
}
|
|
|
|
else if (Status == STATUS_MORE_PROCESSING_REQUIRED)
|
|
|
|
{
|
2013-08-31 16:02:13 +00:00
|
|
|
DPRINTC("DoAcquisition %p\n", Resources.DoAcquisition);
|
2012-03-28 18:39:21 +00:00
|
|
|
|
|
|
|
Status = Resources.DoAcquisition(AddressSpace,
|
|
|
|
MemoryArea,
|
|
|
|
&Resources);
|
|
|
|
|
|
|
|
DPRINTC("Status %x\n", Status);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("bail\n");
|
|
|
|
goto bail;
|
|
|
|
}
|
[NTOSKRNL]
Coverity code defects fixes :
- Cache: CID 701441
- Config: CIDs 716570, 716669, 716760
- Dbgk: Kdbg: CIDs 716571, 515128/9, 500432
- Ex: CIDs 500156/7, 515122, 716200/67, 701301, 514669
- Fsrtl: Fstub: CIDs 701341/2, 701288, 716770, 701302, and CIDs 716576/7/8 + 514636 + 716805 thanks to Thomas Faber
- Io: CIDs 514576, 514643, 514672/3, 716203, 716269, 716581, 716591, 716713
- Ke: CIDs 515125, 716592
- Ps: CIDs 716603/4, 701422
- Ob: Po: CIDs 514671/680, 701419/420/421, 716763, 716601/2
All the details are given in the different bug reports.
CORE-6677 CORE-6679 CORE-6680 CORE-6683 CORE-6686 CORE-6692 CORE-6693 CORE-6694 CORE-6695 CORE-6696 #comment Committed in rev.57400 #resolve #close
svn path=/trunk/; revision=57400
2012-09-27 17:16:31 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
Status = STATUS_MM_RESTART_OPERATION;
|
|
|
|
}
|
2012-03-28 18:39:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
while (Status == STATUS_MM_RESTART_OPERATION);
|
|
|
|
|
|
|
|
if (ProcRef)
|
|
|
|
{
|
|
|
|
ObDereferenceObject(Process);
|
|
|
|
ProcRef = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
ExAcquireFastMutex(&RmapListLock);
|
|
|
|
ASSERT(!MM_IS_WAIT_PTE(MmGetPfnForProcess(Process, Address)));
|
|
|
|
entry = MmGetRmapListHeadPage(Page);
|
|
|
|
|
2013-08-31 16:02:13 +00:00
|
|
|
DPRINTC("Entry %p\n", entry);
|
2012-03-28 18:39:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ExReleaseFastMutex(&RmapListLock);
|
[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
|
|
|
|
|
|
|
bail:
|
2012-03-28 18:39:21 +00:00
|
|
|
DPRINTC("BAIL %x\n", Status);
|
|
|
|
|
|
|
|
if (Segment)
|
|
|
|
{
|
|
|
|
ULONG RefCount;
|
|
|
|
|
2013-08-31 16:02:13 +00:00
|
|
|
DPRINTC("About to finalize section page %x (%p:%x) Status %x %s\n",
|
2012-03-28 18:39:21 +00:00
|
|
|
Page,
|
|
|
|
Segment,
|
|
|
|
FileOffset.LowPart,
|
|
|
|
Status,
|
|
|
|
Dirty ? "dirty" : "clean");
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status) ||
|
|
|
|
!NT_SUCCESS(Status = MmFinalizeSectionPageOut(Segment,
|
|
|
|
&FileOffset,
|
|
|
|
Page,
|
|
|
|
Dirty)))
|
|
|
|
{
|
|
|
|
DPRINTC("Failed to page out %x, replacing %x at %x in segment %x\n",
|
|
|
|
SectionPage,
|
|
|
|
FileOffset.LowPart,
|
|
|
|
Segment);
|
|
|
|
|
|
|
|
MmLockSectionSegment(Segment);
|
|
|
|
|
|
|
|
MmSetPageEntrySectionSegment(Segment,
|
|
|
|
&FileOffset,
|
|
|
|
Dirty ? MAKE_PFN_SSE(Page) : DIRTY_SSE(MAKE_PFN_SSE(Page)));
|
|
|
|
|
|
|
|
MmUnlockSectionSegment(Segment);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Alas, we had the last reference */
|
|
|
|
if ((RefCount = InterlockedDecrementUL(&Segment->ReferenceCount)) == 0)
|
|
|
|
MmFinalizeSegment(Segment);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ProcRef)
|
|
|
|
{
|
|
|
|
DPRINTC("Dereferencing process...\n");
|
|
|
|
ObDereferenceObject(Process);
|
|
|
|
}
|
|
|
|
|
|
|
|
ExReleaseFastMutex(&MiGlobalPageOperation);
|
|
|
|
|
|
|
|
DPRINTC("%s %x %x\n",
|
|
|
|
NT_SUCCESS(Status) ? "Evicted" : "Spared",
|
|
|
|
Page,
|
|
|
|
Status);
|
|
|
|
|
|
|
|
return NT_SUCCESS(Status) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
|
[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
|
|
|
}
|
|
|
|
|
|
|
|
ULONG
|
|
|
|
NTAPI
|
2012-03-28 18:39:21 +00:00
|
|
|
MiCacheEvictPages(PMM_SECTION_SEGMENT Segment,
|
|
|
|
ULONG Target)
|
[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 19:41:40 +00:00
|
|
|
ULONG_PTR Entry;
|
|
|
|
ULONG Result = 0, i, j;
|
2012-03-28 18:39:21 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
PFN_NUMBER Page;
|
|
|
|
LARGE_INTEGER Offset;
|
|
|
|
|
|
|
|
MmLockSectionSegment(Segment);
|
|
|
|
|
|
|
|
for (i = 0; i < RtlNumberGenericTableElements(&Segment->PageTable); i++) {
|
|
|
|
|
|
|
|
PCACHE_SECTION_PAGE_TABLE Element = RtlGetElementGenericTable(&Segment->PageTable,
|
|
|
|
i);
|
|
|
|
|
|
|
|
ASSERT(Element);
|
|
|
|
|
|
|
|
Offset = Element->FileOffset;
|
|
|
|
for (j = 0; j < ENTRIES_PER_ELEMENT; j++, Offset.QuadPart += PAGE_SIZE) {
|
|
|
|
Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
|
|
|
|
if (Entry && !IS_SWAP_FROM_SSE(Entry)) {
|
|
|
|
Page = PFN_FROM_SSE(Entry);
|
|
|
|
MmUnlockSectionSegment(Segment);
|
|
|
|
Status = MmpPageOutPhysicalAddress(Page);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
Result++;
|
|
|
|
MmLockSectionSegment(Segment);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
MmUnlockSectionSegment(Segment);
|
|
|
|
|
|
|
|
return Result;
|
[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
|
|
|
extern LIST_ENTRY MiSegmentList;
|
|
|
|
|
|
|
|
// Interact with legacy balance manager for now
|
|
|
|
// This can fall away when our section implementation supports
|
|
|
|
// demand paging properly
|
|
|
|
NTSTATUS
|
2012-03-28 18:39:21 +00:00
|
|
|
MiRosTrimCache(ULONG Target,
|
|
|
|
ULONG Priority,
|
|
|
|
PULONG NrFreed)
|
[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
|
|
|
{
|
|
|
|
ULONG Freed;
|
|
|
|
PLIST_ENTRY Entry;
|
|
|
|
PMM_SECTION_SEGMENT Segment;
|
|
|
|
*NrFreed = 0;
|
|
|
|
|
2013-08-31 16:02:13 +00:00
|
|
|
DPRINT1("Need to trim %lu cache pages\n", Target);
|
2012-03-28 18:39:21 +00:00
|
|
|
for (Entry = MiSegmentList.Flink;
|
|
|
|
*NrFreed < Target && Entry != &MiSegmentList;
|
|
|
|
Entry = Entry->Flink) {
|
[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
|
|
|
Segment = CONTAINING_RECORD(Entry, MM_SECTION_SEGMENT, ListOfSegments);
|
2012-03-28 18:39:21 +00:00
|
|
|
/* Defer to MM to try recovering pages from it */
|
[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
|
|
|
Freed = MiCacheEvictPages(Segment, Target);
|
|
|
|
*NrFreed += Freed;
|
|
|
|
}
|
2013-08-31 16:02:13 +00:00
|
|
|
DPRINT1("Evicted %lu cache pages\n", Target);
|
[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 (!IsListEmpty(&MiSegmentList)) {
|
|
|
|
Entry = MiSegmentList.Flink;
|
|
|
|
RemoveEntryList(Entry);
|
|
|
|
InsertTailList(&MiSegmentList, Entry);
|
|
|
|
}
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|