2023-10-09 23:33:53 +00:00
|
|
|
/*
|
2008-02-14 03:08:20 +00:00
|
|
|
* PROJECT: ReactOS Kernel
|
|
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
2005-01-26 13:58:37 +00:00
|
|
|
* FILE: ntoskrnl/mm/mminit.c
|
2008-02-14 03:08:20 +00:00
|
|
|
* PURPOSE: Memory Manager Initialization
|
2011-12-25 18:21:05 +00:00
|
|
|
* PROGRAMMERS:
|
2000-07-04 08:52:47 +00:00
|
|
|
*/
|
|
|
|
|
2008-02-14 03:08:20 +00:00
|
|
|
/* INCLUDES ******************************************************************/
|
2000-07-04 08:52:47 +00:00
|
|
|
|
2004-08-15 16:39:12 +00:00
|
|
|
#include <ntoskrnl.h>
|
2008-01-06 15:12:41 +00:00
|
|
|
#define NDEBUG
|
2008-08-30 16:31:06 +00:00
|
|
|
#include <debug.h>
|
2000-07-04 08:52:47 +00:00
|
|
|
|
- Fix a bug in memory area creation: Static memory areas had the static flag embedded in their type, so code that was switch()ing on the type would fail to recognize the actual type, because MEMORY_AREA_STATIC was ORed in.
- Add a new memory area type: MEMORY_AREA_OWNED_BY_ARM3. This will allow us to instruct the ReactOS Memory MAnager to "Back. The Fuck. Off." during page faults and such, so we can handle page faults inside ARM3-owned PTEs ourselves.
- Right now, all ARM3 PTEs and data is nonpaged, so no page faults should happen, but this may change in the future.
- Also will allow us to manage our own PDEs so we can do on-demand inpage instead of syncing with the ReactOS Mm hack cache.
- Create all memory areas in one shot in MmCreateSystemMemoryAreas (get rid of MiInitPageDirectoryMap and MiInitPagedPool memory area creation).
- Mark all of ours as owned by ARM3.
- Make them all static.
- The only non-ARM3 one right now is paged pool, we own all the other static areas.
- Move this code into mm, instead of mm/ARM3, since memory areas are not an ARM3 concept.
- Also create memory areas for session space, session view, and other ARM3 memory ranges, so nobody touches those ranges.
- Dump the kernel address space after all this is done, in a MmDbg function in mm.
- This cleans up ARM3 of some ROS-specific code, and also collapses Phase 1 and 2 into a single phase.
svn path=/trunk/; revision=43486
2009-10-15 18:54:35 +00:00
|
|
|
#define MODULE_INVOLVED_IN_ARM3
|
|
|
|
#include "ARM3/miarm.h"
|
|
|
|
|
2008-02-14 03:08:20 +00:00
|
|
|
/* GLOBALS *******************************************************************/
|
2007-10-02 20:09:31 +00:00
|
|
|
|
2010-03-29 04:49:07 +00:00
|
|
|
BOOLEAN Mm64BitPhysicalAddress = FALSE;
|
- Create mmsup.c in ReactOS memory manager directory. It hosts misc support functions:
- Copy kmap.c here, since it's the very definition of "misc support function"
- Copy some exported functions in mm.c which were listed as "misc functions"
- Warn that current implementation of MmIsNonPagedSystemAddressValid will kill kittens.
- Rename mm.c to mmfault.c, since other than the misc functions now in mmsup.c, it was all routines to handle page/access faults.
- Warn that MmIsAddressValid, as currently implemented, kills puppies.
- Move WriteWatch functions to virtual.c since they're part of the Virtual API system call set already hosted there.
- Move the global variables that people had been throwing in here to mminit.c, which is slightly more appropriate.
- Move wset.c's MmTrimUserMemory to balance.c, since that's where all other similar functions are located.
- Incidentally, kill wset.c, as this was the only function present.
- No functional changes, just refactoring and cleanup (other than warning the critter murder the two broken functions will achieve if called).
svn path=/trunk/; revision=41659
2009-06-28 07:52:30 +00:00
|
|
|
ULONG MmReadClusterSize;
|
2009-10-19 23:04:50 +00:00
|
|
|
//
|
|
|
|
// 0 | 1 is on/off paging, 2 is undocumented
|
|
|
|
//
|
|
|
|
UCHAR MmDisablePagingExecutive = 1; // Forced to off
|
2009-07-27 02:13:19 +00:00
|
|
|
PMMPTE MmSharedUserDataPte;
|
- Create mmsup.c in ReactOS memory manager directory. It hosts misc support functions:
- Copy kmap.c here, since it's the very definition of "misc support function"
- Copy some exported functions in mm.c which were listed as "misc functions"
- Warn that current implementation of MmIsNonPagedSystemAddressValid will kill kittens.
- Rename mm.c to mmfault.c, since other than the misc functions now in mmsup.c, it was all routines to handle page/access faults.
- Warn that MmIsAddressValid, as currently implemented, kills puppies.
- Move WriteWatch functions to virtual.c since they're part of the Virtual API system call set already hosted there.
- Move the global variables that people had been throwing in here to mminit.c, which is slightly more appropriate.
- Move wset.c's MmTrimUserMemory to balance.c, since that's where all other similar functions are located.
- Incidentally, kill wset.c, as this was the only function present.
- No functional changes, just refactoring and cleanup (other than warning the critter murder the two broken functions will achieve if called).
svn path=/trunk/; revision=41659
2009-06-28 07:52:30 +00:00
|
|
|
PMMSUPPORT MmKernelAddressSpace;
|
2007-09-27 18:07:44 +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 KEVENT MmWaitPageEvent;
|
|
|
|
extern FAST_MUTEX MiGlobalPageOperation;
|
|
|
|
extern LIST_ENTRY MiSegmentList;
|
|
|
|
extern NTSTATUS MiRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed);
|
|
|
|
|
2008-02-14 03:08:20 +00:00
|
|
|
/* PRIVATE FUNCTIONS *********************************************************/
|
2000-07-04 08:52:47 +00:00
|
|
|
|
2015-07-19 08:29:58 +00:00
|
|
|
//
|
|
|
|
// Helper function to create initial memory areas.
|
|
|
|
// The created area is always read/write.
|
|
|
|
//
|
2020-10-06 19:44:01 +00:00
|
|
|
CODE_SEG("INIT")
|
2018-12-30 11:19:11 +00:00
|
|
|
VOID
|
2005-09-14 01:05:50 +00:00
|
|
|
NTAPI
|
2017-11-10 17:19:45 +00:00
|
|
|
MiCreateArm3StaticMemoryArea(PVOID BaseAddress, SIZE_T Size, BOOLEAN Executable)
|
2000-07-04 08:52:47 +00:00
|
|
|
{
|
2015-07-19 08:29:58 +00:00
|
|
|
const ULONG Protection = Executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
|
|
|
|
PVOID pBaseAddress = BaseAddress;
|
2009-06-21 06:36:45 +00:00
|
|
|
PMEMORY_AREA MArea;
|
- Fix a bug in memory area creation: Static memory areas had the static flag embedded in their type, so code that was switch()ing on the type would fail to recognize the actual type, because MEMORY_AREA_STATIC was ORed in.
- Add a new memory area type: MEMORY_AREA_OWNED_BY_ARM3. This will allow us to instruct the ReactOS Memory MAnager to "Back. The Fuck. Off." during page faults and such, so we can handle page faults inside ARM3-owned PTEs ourselves.
- Right now, all ARM3 PTEs and data is nonpaged, so no page faults should happen, but this may change in the future.
- Also will allow us to manage our own PDEs so we can do on-demand inpage instead of syncing with the ReactOS Mm hack cache.
- Create all memory areas in one shot in MmCreateSystemMemoryAreas (get rid of MiInitPageDirectoryMap and MiInitPagedPool memory area creation).
- Mark all of ours as owned by ARM3.
- Make them all static.
- The only non-ARM3 one right now is paged pool, we own all the other static areas.
- Move this code into mm, instead of mm/ARM3, since memory areas are not an ARM3 concept.
- Also create memory areas for session space, session view, and other ARM3 memory ranges, so nobody touches those ranges.
- Dump the kernel address space after all this is done, in a MmDbg function in mm.
- This cleans up ARM3 of some ROS-specific code, and also collapses Phase 1 and 2 into a single phase.
svn path=/trunk/; revision=43486
2009-10-15 18:54:35 +00:00
|
|
|
NTSTATUS Status;
|
2011-12-25 18:21:05 +00:00
|
|
|
|
2012-02-03 20:59:35 +00:00
|
|
|
Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
|
|
|
|
MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC,
|
2015-07-19 08:29:58 +00:00
|
|
|
&pBaseAddress,
|
|
|
|
Size,
|
|
|
|
Protection,
|
2012-02-03 20:59:35 +00:00
|
|
|
&MArea,
|
|
|
|
0,
|
2013-11-26 21:38:02 +00:00
|
|
|
PAGE_SIZE);
|
2012-02-03 20:59:35 +00:00
|
|
|
ASSERT(Status == STATUS_SUCCESS);
|
2015-07-19 08:29:58 +00:00
|
|
|
// TODO: Perhaps it would be prudent to bugcheck here, not only assert?
|
|
|
|
}
|
2012-02-03 20:59:35 +00:00
|
|
|
|
2020-10-06 19:44:01 +00:00
|
|
|
CODE_SEG("INIT")
|
2018-12-30 11:19:11 +00:00
|
|
|
VOID
|
2015-07-19 08:29:58 +00:00
|
|
|
NTAPI
|
2015-09-03 23:57:39 +00:00
|
|
|
MiInitSystemMemoryAreas(VOID)
|
2015-07-19 08:29:58 +00:00
|
|
|
{
|
2009-06-21 06:36:45 +00:00
|
|
|
//
|
2015-07-19 08:29:58 +00:00
|
|
|
// Create all the static memory areas.
|
- Fix a bug in memory area creation: Static memory areas had the static flag embedded in their type, so code that was switch()ing on the type would fail to recognize the actual type, because MEMORY_AREA_STATIC was ORed in.
- Add a new memory area type: MEMORY_AREA_OWNED_BY_ARM3. This will allow us to instruct the ReactOS Memory MAnager to "Back. The Fuck. Off." during page faults and such, so we can handle page faults inside ARM3-owned PTEs ourselves.
- Right now, all ARM3 PTEs and data is nonpaged, so no page faults should happen, but this may change in the future.
- Also will allow us to manage our own PDEs so we can do on-demand inpage instead of syncing with the ReactOS Mm hack cache.
- Create all memory areas in one shot in MmCreateSystemMemoryAreas (get rid of MiInitPageDirectoryMap and MiInitPagedPool memory area creation).
- Mark all of ours as owned by ARM3.
- Make them all static.
- The only non-ARM3 one right now is paged pool, we own all the other static areas.
- Move this code into mm, instead of mm/ARM3, since memory areas are not an ARM3 concept.
- Also create memory areas for session space, session view, and other ARM3 memory ranges, so nobody touches those ranges.
- Dump the kernel address space after all this is done, in a MmDbg function in mm.
- This cleans up ARM3 of some ROS-specific code, and also collapses Phase 1 and 2 into a single phase.
svn path=/trunk/; revision=43486
2009-10-15 18:54:35 +00:00
|
|
|
//
|
2011-12-25 18:21:05 +00:00
|
|
|
|
2023-10-09 23:33:53 +00:00
|
|
|
MmLockAddressSpace(MmGetKernelAddressSpace());
|
|
|
|
|
2018-01-29 11:39:21 +00:00
|
|
|
#ifdef _M_AMD64
|
|
|
|
// Reserved range FFFF800000000000 - FFFFF68000000000
|
|
|
|
MiCreateArm3StaticMemoryArea((PVOID)MI_REAL_SYSTEM_RANGE_START, PTE_BASE - MI_REAL_SYSTEM_RANGE_START, FALSE);
|
|
|
|
#endif /* _M_AMD64 */
|
|
|
|
|
2015-07-19 08:29:58 +00:00
|
|
|
// The loader mappings. The only Executable area.
|
|
|
|
MiCreateArm3StaticMemoryArea((PVOID)KSEG0_BASE, MmBootImageSize, TRUE);
|
|
|
|
|
|
|
|
// The PTE base
|
|
|
|
MiCreateArm3StaticMemoryArea((PVOID)PTE_BASE, PTE_TOP - PTE_BASE + 1, FALSE);
|
|
|
|
|
|
|
|
// Hyperspace
|
|
|
|
MiCreateArm3StaticMemoryArea((PVOID)HYPER_SPACE, HYPER_SPACE_END - HYPER_SPACE + 1, FALSE);
|
2011-12-25 18:21:05 +00:00
|
|
|
|
- Fix a bug in memory area creation: Static memory areas had the static flag embedded in their type, so code that was switch()ing on the type would fail to recognize the actual type, because MEMORY_AREA_STATIC was ORed in.
- Add a new memory area type: MEMORY_AREA_OWNED_BY_ARM3. This will allow us to instruct the ReactOS Memory MAnager to "Back. The Fuck. Off." during page faults and such, so we can handle page faults inside ARM3-owned PTEs ourselves.
- Right now, all ARM3 PTEs and data is nonpaged, so no page faults should happen, but this may change in the future.
- Also will allow us to manage our own PDEs so we can do on-demand inpage instead of syncing with the ReactOS Mm hack cache.
- Create all memory areas in one shot in MmCreateSystemMemoryAreas (get rid of MiInitPageDirectoryMap and MiInitPagedPool memory area creation).
- Mark all of ours as owned by ARM3.
- Make them all static.
- The only non-ARM3 one right now is paged pool, we own all the other static areas.
- Move this code into mm, instead of mm/ARM3, since memory areas are not an ARM3 concept.
- Also create memory areas for session space, session view, and other ARM3 memory ranges, so nobody touches those ranges.
- Dump the kernel address space after all this is done, in a MmDbg function in mm.
- This cleans up ARM3 of some ROS-specific code, and also collapses Phase 1 and 2 into a single phase.
svn path=/trunk/; revision=43486
2009-10-15 18:54:35 +00:00
|
|
|
// Protect the PFN database
|
2015-07-19 08:29:58 +00:00
|
|
|
MiCreateArm3StaticMemoryArea(MmPfnDatabase, (MxPfnAllocation << PAGE_SHIFT), FALSE);
|
2011-12-25 18:21:05 +00:00
|
|
|
|
- Fix a bug in memory area creation: Static memory areas had the static flag embedded in their type, so code that was switch()ing on the type would fail to recognize the actual type, because MEMORY_AREA_STATIC was ORed in.
- Add a new memory area type: MEMORY_AREA_OWNED_BY_ARM3. This will allow us to instruct the ReactOS Memory MAnager to "Back. The Fuck. Off." during page faults and such, so we can handle page faults inside ARM3-owned PTEs ourselves.
- Right now, all ARM3 PTEs and data is nonpaged, so no page faults should happen, but this may change in the future.
- Also will allow us to manage our own PDEs so we can do on-demand inpage instead of syncing with the ReactOS Mm hack cache.
- Create all memory areas in one shot in MmCreateSystemMemoryAreas (get rid of MiInitPageDirectoryMap and MiInitPagedPool memory area creation).
- Mark all of ours as owned by ARM3.
- Make them all static.
- The only non-ARM3 one right now is paged pool, we own all the other static areas.
- Move this code into mm, instead of mm/ARM3, since memory areas are not an ARM3 concept.
- Also create memory areas for session space, session view, and other ARM3 memory ranges, so nobody touches those ranges.
- Dump the kernel address space after all this is done, in a MmDbg function in mm.
- This cleans up ARM3 of some ROS-specific code, and also collapses Phase 1 and 2 into a single phase.
svn path=/trunk/; revision=43486
2009-10-15 18:54:35 +00:00
|
|
|
// ReactOS requires a memory area to keep the initial NP area off-bounds
|
2015-07-19 08:29:58 +00:00
|
|
|
MiCreateArm3StaticMemoryArea(MmNonPagedPoolStart, MmSizeOfNonPagedPoolInBytes, FALSE);
|
2011-12-25 18:21:05 +00:00
|
|
|
|
2016-09-30 15:58:23 +00:00
|
|
|
// System PTE space
|
|
|
|
MiCreateArm3StaticMemoryArea(MmNonPagedSystemStart, (MmNumberOfSystemPtes + 1) * PAGE_SIZE, FALSE);
|
|
|
|
|
|
|
|
// Nonpaged pool expansion space
|
|
|
|
MiCreateArm3StaticMemoryArea(MmNonPagedPoolExpansionStart, (ULONG_PTR)MmNonPagedPoolEnd - (ULONG_PTR)MmNonPagedPoolExpansionStart, FALSE);
|
2011-12-25 18:21:05 +00:00
|
|
|
|
2015-07-19 08:29:58 +00:00
|
|
|
// System view space
|
|
|
|
MiCreateArm3StaticMemoryArea(MiSystemViewStart, MmSystemViewSize, FALSE);
|
2011-12-25 18:21:05 +00:00
|
|
|
|
2015-07-19 08:29:58 +00:00
|
|
|
// Session space
|
|
|
|
MiCreateArm3StaticMemoryArea(MmSessionBase, (ULONG_PTR)MiSessionSpaceEnd - (ULONG_PTR)MmSessionBase, FALSE);
|
|
|
|
|
|
|
|
// Paged pool
|
|
|
|
MiCreateArm3StaticMemoryArea(MmPagedPoolStart, MmSizeOfPagedPoolInBytes, FALSE);
|
2011-12-25 18:21:05 +00:00
|
|
|
|
2016-08-09 07:48:09 +00:00
|
|
|
// Debugger mapping
|
|
|
|
MiCreateArm3StaticMemoryArea(MI_DEBUG_MAPPING, PAGE_SIZE, FALSE);
|
|
|
|
|
|
|
|
#if defined(_X86_)
|
|
|
|
// Reserved HAL area (includes KUSER_SHARED_DATA and KPCR)
|
|
|
|
MiCreateArm3StaticMemoryArea((PVOID)MM_HAL_VA_START, MM_HAL_VA_END - MM_HAL_VA_START + 1, FALSE);
|
|
|
|
#else /* _X86_ */
|
2012-02-03 20:59:35 +00:00
|
|
|
#ifndef _M_AMD64
|
2015-07-19 08:29:58 +00:00
|
|
|
// KPCR, one page per CPU. Only for 32-bit kernel.
|
|
|
|
MiCreateArm3StaticMemoryArea(PCR, PAGE_SIZE * KeNumberProcessors, FALSE);
|
2016-08-09 07:48:09 +00:00
|
|
|
#endif /* _M_AMD64 */
|
2009-11-04 22:40:18 +00:00
|
|
|
|
2015-07-19 08:29:58 +00:00
|
|
|
// KUSER_SHARED_DATA
|
|
|
|
MiCreateArm3StaticMemoryArea((PVOID)KI_USER_SHARED_DATA, PAGE_SIZE, FALSE);
|
2016-08-09 07:48:09 +00:00
|
|
|
#endif /* _X86_ */
|
2023-10-09 23:33:53 +00:00
|
|
|
|
|
|
|
MmUnlockAddressSpace(MmGetKernelAddressSpace());
|
2000-07-04 08:52:47 +00:00
|
|
|
}
|
|
|
|
|
2020-10-06 19:44:01 +00:00
|
|
|
CODE_SEG("INIT")
|
- Fix a bug in memory area creation: Static memory areas had the static flag embedded in their type, so code that was switch()ing on the type would fail to recognize the actual type, because MEMORY_AREA_STATIC was ORed in.
- Add a new memory area type: MEMORY_AREA_OWNED_BY_ARM3. This will allow us to instruct the ReactOS Memory MAnager to "Back. The Fuck. Off." during page faults and such, so we can handle page faults inside ARM3-owned PTEs ourselves.
- Right now, all ARM3 PTEs and data is nonpaged, so no page faults should happen, but this may change in the future.
- Also will allow us to manage our own PDEs so we can do on-demand inpage instead of syncing with the ReactOS Mm hack cache.
- Create all memory areas in one shot in MmCreateSystemMemoryAreas (get rid of MiInitPageDirectoryMap and MiInitPagedPool memory area creation).
- Mark all of ours as owned by ARM3.
- Make them all static.
- The only non-ARM3 one right now is paged pool, we own all the other static areas.
- Move this code into mm, instead of mm/ARM3, since memory areas are not an ARM3 concept.
- Also create memory areas for session space, session view, and other ARM3 memory ranges, so nobody touches those ranges.
- Dump the kernel address space after all this is done, in a MmDbg function in mm.
- This cleans up ARM3 of some ROS-specific code, and also collapses Phase 1 and 2 into a single phase.
svn path=/trunk/; revision=43486
2009-10-15 18:54:35 +00:00
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
MiDbgDumpAddressSpace(VOID)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// Print the memory layout
|
|
|
|
//
|
|
|
|
DPRINT1(" 0x%p - 0x%p\t%s\n",
|
2012-02-03 20:59:35 +00:00
|
|
|
KSEG0_BASE,
|
|
|
|
(ULONG_PTR)KSEG0_BASE + MmBootImageSize,
|
- Fix a bug in memory area creation: Static memory areas had the static flag embedded in their type, so code that was switch()ing on the type would fail to recognize the actual type, because MEMORY_AREA_STATIC was ORed in.
- Add a new memory area type: MEMORY_AREA_OWNED_BY_ARM3. This will allow us to instruct the ReactOS Memory MAnager to "Back. The Fuck. Off." during page faults and such, so we can handle page faults inside ARM3-owned PTEs ourselves.
- Right now, all ARM3 PTEs and data is nonpaged, so no page faults should happen, but this may change in the future.
- Also will allow us to manage our own PDEs so we can do on-demand inpage instead of syncing with the ReactOS Mm hack cache.
- Create all memory areas in one shot in MmCreateSystemMemoryAreas (get rid of MiInitPageDirectoryMap and MiInitPagedPool memory area creation).
- Mark all of ours as owned by ARM3.
- Make them all static.
- The only non-ARM3 one right now is paged pool, we own all the other static areas.
- Move this code into mm, instead of mm/ARM3, since memory areas are not an ARM3 concept.
- Also create memory areas for session space, session view, and other ARM3 memory ranges, so nobody touches those ranges.
- Dump the kernel address space after all this is done, in a MmDbg function in mm.
- This cleans up ARM3 of some ROS-specific code, and also collapses Phase 1 and 2 into a single phase.
svn path=/trunk/; revision=43486
2009-10-15 18:54:35 +00:00
|
|
|
"Boot Loaded Image");
|
|
|
|
DPRINT1(" 0x%p - 0x%p\t%s\n",
|
2010-06-06 15:59:42 +00:00
|
|
|
MmPfnDatabase,
|
|
|
|
(ULONG_PTR)MmPfnDatabase + (MxPfnAllocation << PAGE_SHIFT),
|
- Fix a bug in memory area creation: Static memory areas had the static flag embedded in their type, so code that was switch()ing on the type would fail to recognize the actual type, because MEMORY_AREA_STATIC was ORed in.
- Add a new memory area type: MEMORY_AREA_OWNED_BY_ARM3. This will allow us to instruct the ReactOS Memory MAnager to "Back. The Fuck. Off." during page faults and such, so we can handle page faults inside ARM3-owned PTEs ourselves.
- Right now, all ARM3 PTEs and data is nonpaged, so no page faults should happen, but this may change in the future.
- Also will allow us to manage our own PDEs so we can do on-demand inpage instead of syncing with the ReactOS Mm hack cache.
- Create all memory areas in one shot in MmCreateSystemMemoryAreas (get rid of MiInitPageDirectoryMap and MiInitPagedPool memory area creation).
- Mark all of ours as owned by ARM3.
- Make them all static.
- The only non-ARM3 one right now is paged pool, we own all the other static areas.
- Move this code into mm, instead of mm/ARM3, since memory areas are not an ARM3 concept.
- Also create memory areas for session space, session view, and other ARM3 memory ranges, so nobody touches those ranges.
- Dump the kernel address space after all this is done, in a MmDbg function in mm.
- This cleans up ARM3 of some ROS-specific code, and also collapses Phase 1 and 2 into a single phase.
svn path=/trunk/; revision=43486
2009-10-15 18:54:35 +00:00
|
|
|
"PFN Database");
|
|
|
|
DPRINT1(" 0x%p - 0x%p\t%s\n",
|
|
|
|
MmNonPagedPoolStart,
|
|
|
|
(ULONG_PTR)MmNonPagedPoolStart + MmSizeOfNonPagedPoolInBytes,
|
2012-02-22 21:18:56 +00:00
|
|
|
"ARM3 Non Paged Pool");
|
- Fix a bug in memory area creation: Static memory areas had the static flag embedded in their type, so code that was switch()ing on the type would fail to recognize the actual type, because MEMORY_AREA_STATIC was ORed in.
- Add a new memory area type: MEMORY_AREA_OWNED_BY_ARM3. This will allow us to instruct the ReactOS Memory MAnager to "Back. The Fuck. Off." during page faults and such, so we can handle page faults inside ARM3-owned PTEs ourselves.
- Right now, all ARM3 PTEs and data is nonpaged, so no page faults should happen, but this may change in the future.
- Also will allow us to manage our own PDEs so we can do on-demand inpage instead of syncing with the ReactOS Mm hack cache.
- Create all memory areas in one shot in MmCreateSystemMemoryAreas (get rid of MiInitPageDirectoryMap and MiInitPagedPool memory area creation).
- Mark all of ours as owned by ARM3.
- Make them all static.
- The only non-ARM3 one right now is paged pool, we own all the other static areas.
- Move this code into mm, instead of mm/ARM3, since memory areas are not an ARM3 concept.
- Also create memory areas for session space, session view, and other ARM3 memory ranges, so nobody touches those ranges.
- Dump the kernel address space after all this is done, in a MmDbg function in mm.
- This cleans up ARM3 of some ROS-specific code, and also collapses Phase 1 and 2 into a single phase.
svn path=/trunk/; revision=43486
2009-10-15 18:54:35 +00:00
|
|
|
DPRINT1(" 0x%p - 0x%p\t%s\n",
|
|
|
|
MiSystemViewStart,
|
|
|
|
(ULONG_PTR)MiSystemViewStart + MmSystemViewSize,
|
2011-12-25 18:21:05 +00:00
|
|
|
"System View Space");
|
- Fix a bug in memory area creation: Static memory areas had the static flag embedded in their type, so code that was switch()ing on the type would fail to recognize the actual type, because MEMORY_AREA_STATIC was ORed in.
- Add a new memory area type: MEMORY_AREA_OWNED_BY_ARM3. This will allow us to instruct the ReactOS Memory MAnager to "Back. The Fuck. Off." during page faults and such, so we can handle page faults inside ARM3-owned PTEs ourselves.
- Right now, all ARM3 PTEs and data is nonpaged, so no page faults should happen, but this may change in the future.
- Also will allow us to manage our own PDEs so we can do on-demand inpage instead of syncing with the ReactOS Mm hack cache.
- Create all memory areas in one shot in MmCreateSystemMemoryAreas (get rid of MiInitPageDirectoryMap and MiInitPagedPool memory area creation).
- Mark all of ours as owned by ARM3.
- Make them all static.
- The only non-ARM3 one right now is paged pool, we own all the other static areas.
- Move this code into mm, instead of mm/ARM3, since memory areas are not an ARM3 concept.
- Also create memory areas for session space, session view, and other ARM3 memory ranges, so nobody touches those ranges.
- Dump the kernel address space after all this is done, in a MmDbg function in mm.
- This cleans up ARM3 of some ROS-specific code, and also collapses Phase 1 and 2 into a single phase.
svn path=/trunk/; revision=43486
2009-10-15 18:54:35 +00:00
|
|
|
DPRINT1(" 0x%p - 0x%p\t%s\n",
|
|
|
|
MmSessionBase,
|
|
|
|
MiSessionSpaceEnd,
|
|
|
|
"Session Space");
|
|
|
|
DPRINT1(" 0x%p - 0x%p\t%s\n",
|
2012-02-03 20:59:35 +00:00
|
|
|
PTE_BASE, PTE_TOP,
|
- Fix a bug in memory area creation: Static memory areas had the static flag embedded in their type, so code that was switch()ing on the type would fail to recognize the actual type, because MEMORY_AREA_STATIC was ORed in.
- Add a new memory area type: MEMORY_AREA_OWNED_BY_ARM3. This will allow us to instruct the ReactOS Memory MAnager to "Back. The Fuck. Off." during page faults and such, so we can handle page faults inside ARM3-owned PTEs ourselves.
- Right now, all ARM3 PTEs and data is nonpaged, so no page faults should happen, but this may change in the future.
- Also will allow us to manage our own PDEs so we can do on-demand inpage instead of syncing with the ReactOS Mm hack cache.
- Create all memory areas in one shot in MmCreateSystemMemoryAreas (get rid of MiInitPageDirectoryMap and MiInitPagedPool memory area creation).
- Mark all of ours as owned by ARM3.
- Make them all static.
- The only non-ARM3 one right now is paged pool, we own all the other static areas.
- Move this code into mm, instead of mm/ARM3, since memory areas are not an ARM3 concept.
- Also create memory areas for session space, session view, and other ARM3 memory ranges, so nobody touches those ranges.
- Dump the kernel address space after all this is done, in a MmDbg function in mm.
- This cleans up ARM3 of some ROS-specific code, and also collapses Phase 1 and 2 into a single phase.
svn path=/trunk/; revision=43486
2009-10-15 18:54:35 +00:00
|
|
|
"Page Tables");
|
|
|
|
DPRINT1(" 0x%p - 0x%p\t%s\n",
|
2012-02-03 20:59:35 +00:00
|
|
|
PDE_BASE, PDE_TOP,
|
- Fix a bug in memory area creation: Static memory areas had the static flag embedded in their type, so code that was switch()ing on the type would fail to recognize the actual type, because MEMORY_AREA_STATIC was ORed in.
- Add a new memory area type: MEMORY_AREA_OWNED_BY_ARM3. This will allow us to instruct the ReactOS Memory MAnager to "Back. The Fuck. Off." during page faults and such, so we can handle page faults inside ARM3-owned PTEs ourselves.
- Right now, all ARM3 PTEs and data is nonpaged, so no page faults should happen, but this may change in the future.
- Also will allow us to manage our own PDEs so we can do on-demand inpage instead of syncing with the ReactOS Mm hack cache.
- Create all memory areas in one shot in MmCreateSystemMemoryAreas (get rid of MiInitPageDirectoryMap and MiInitPagedPool memory area creation).
- Mark all of ours as owned by ARM3.
- Make them all static.
- The only non-ARM3 one right now is paged pool, we own all the other static areas.
- Move this code into mm, instead of mm/ARM3, since memory areas are not an ARM3 concept.
- Also create memory areas for session space, session view, and other ARM3 memory ranges, so nobody touches those ranges.
- Dump the kernel address space after all this is done, in a MmDbg function in mm.
- This cleans up ARM3 of some ROS-specific code, and also collapses Phase 1 and 2 into a single phase.
svn path=/trunk/; revision=43486
2009-10-15 18:54:35 +00:00
|
|
|
"Page Directories");
|
|
|
|
DPRINT1(" 0x%p - 0x%p\t%s\n",
|
2012-02-03 20:59:35 +00:00
|
|
|
HYPER_SPACE, HYPER_SPACE_END,
|
- Fix a bug in memory area creation: Static memory areas had the static flag embedded in their type, so code that was switch()ing on the type would fail to recognize the actual type, because MEMORY_AREA_STATIC was ORed in.
- Add a new memory area type: MEMORY_AREA_OWNED_BY_ARM3. This will allow us to instruct the ReactOS Memory MAnager to "Back. The Fuck. Off." during page faults and such, so we can handle page faults inside ARM3-owned PTEs ourselves.
- Right now, all ARM3 PTEs and data is nonpaged, so no page faults should happen, but this may change in the future.
- Also will allow us to manage our own PDEs so we can do on-demand inpage instead of syncing with the ReactOS Mm hack cache.
- Create all memory areas in one shot in MmCreateSystemMemoryAreas (get rid of MiInitPageDirectoryMap and MiInitPagedPool memory area creation).
- Mark all of ours as owned by ARM3.
- Make them all static.
- The only non-ARM3 one right now is paged pool, we own all the other static areas.
- Move this code into mm, instead of mm/ARM3, since memory areas are not an ARM3 concept.
- Also create memory areas for session space, session view, and other ARM3 memory ranges, so nobody touches those ranges.
- Dump the kernel address space after all this is done, in a MmDbg function in mm.
- This cleans up ARM3 of some ROS-specific code, and also collapses Phase 1 and 2 into a single phase.
svn path=/trunk/; revision=43486
2009-10-15 18:54:35 +00:00
|
|
|
"Hyperspace");
|
2018-02-06 12:38:55 +00:00
|
|
|
DPRINT1(" 0x%p - 0x%p\t%s\n",
|
|
|
|
MmSystemCacheStart, MmSystemCacheEnd,
|
|
|
|
"System Cache");
|
- Fix a bug in memory area creation: Static memory areas had the static flag embedded in their type, so code that was switch()ing on the type would fail to recognize the actual type, because MEMORY_AREA_STATIC was ORed in.
- Add a new memory area type: MEMORY_AREA_OWNED_BY_ARM3. This will allow us to instruct the ReactOS Memory MAnager to "Back. The Fuck. Off." during page faults and such, so we can handle page faults inside ARM3-owned PTEs ourselves.
- Right now, all ARM3 PTEs and data is nonpaged, so no page faults should happen, but this may change in the future.
- Also will allow us to manage our own PDEs so we can do on-demand inpage instead of syncing with the ReactOS Mm hack cache.
- Create all memory areas in one shot in MmCreateSystemMemoryAreas (get rid of MiInitPageDirectoryMap and MiInitPagedPool memory area creation).
- Mark all of ours as owned by ARM3.
- Make them all static.
- The only non-ARM3 one right now is paged pool, we own all the other static areas.
- Move this code into mm, instead of mm/ARM3, since memory areas are not an ARM3 concept.
- Also create memory areas for session space, session view, and other ARM3 memory ranges, so nobody touches those ranges.
- Dump the kernel address space after all this is done, in a MmDbg function in mm.
- This cleans up ARM3 of some ROS-specific code, and also collapses Phase 1 and 2 into a single phase.
svn path=/trunk/; revision=43486
2009-10-15 18:54:35 +00:00
|
|
|
DPRINT1(" 0x%p - 0x%p\t%s\n",
|
|
|
|
MmPagedPoolStart,
|
|
|
|
(ULONG_PTR)MmPagedPoolStart + MmSizeOfPagedPoolInBytes,
|
2012-02-22 21:18:56 +00:00
|
|
|
"ARM3 Paged Pool");
|
- Fix a bug in memory area creation: Static memory areas had the static flag embedded in their type, so code that was switch()ing on the type would fail to recognize the actual type, because MEMORY_AREA_STATIC was ORed in.
- Add a new memory area type: MEMORY_AREA_OWNED_BY_ARM3. This will allow us to instruct the ReactOS Memory MAnager to "Back. The Fuck. Off." during page faults and such, so we can handle page faults inside ARM3-owned PTEs ourselves.
- Right now, all ARM3 PTEs and data is nonpaged, so no page faults should happen, but this may change in the future.
- Also will allow us to manage our own PDEs so we can do on-demand inpage instead of syncing with the ReactOS Mm hack cache.
- Create all memory areas in one shot in MmCreateSystemMemoryAreas (get rid of MiInitPageDirectoryMap and MiInitPagedPool memory area creation).
- Mark all of ours as owned by ARM3.
- Make them all static.
- The only non-ARM3 one right now is paged pool, we own all the other static areas.
- Move this code into mm, instead of mm/ARM3, since memory areas are not an ARM3 concept.
- Also create memory areas for session space, session view, and other ARM3 memory ranges, so nobody touches those ranges.
- Dump the kernel address space after all this is done, in a MmDbg function in mm.
- This cleans up ARM3 of some ROS-specific code, and also collapses Phase 1 and 2 into a single phase.
svn path=/trunk/; revision=43486
2009-10-15 18:54:35 +00:00
|
|
|
DPRINT1(" 0x%p - 0x%p\t%s\n",
|
|
|
|
MmNonPagedSystemStart, MmNonPagedPoolExpansionStart,
|
|
|
|
"System PTE Space");
|
|
|
|
DPRINT1(" 0x%p - 0x%p\t%s\n",
|
|
|
|
MmNonPagedPoolExpansionStart, MmNonPagedPoolEnd,
|
|
|
|
"Non Paged Pool Expansion PTE Space");
|
|
|
|
}
|
|
|
|
|
2020-10-06 19:44:01 +00:00
|
|
|
CODE_SEG("INIT")
|
2010-10-05 15:55:52 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
MmInitBsmThread(VOID)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
HANDLE ThreadHandle;
|
|
|
|
|
|
|
|
/* Create the thread */
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
|
|
|
|
Status = PsCreateSystemThread(&ThreadHandle,
|
|
|
|
THREAD_ALL_ACCESS,
|
|
|
|
&ObjectAttributes,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
KeBalanceSetManager,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
/* Close the handle and return status */
|
|
|
|
ZwClose(ThreadHandle);
|
|
|
|
return Status;
|
|
|
|
}
|
[NTOS]: Instead of having an LRU linked list of working set pages, we instead have a bitmap.
Advantage: Pages are only in a linked list when they are NOT active (free/zeroed, for now). This makes the LIST_ENTRY fields usable when a page is active, so we can store data in there. This will make it easier to sync our PFN format with Windows.
Advantage: It's a lot faster to set/clear bits than to do list operations (both still O1 though). Scanning for the bit is a bit slower than parsing a list, on the other hand, so it's a toss.
Disadvantage: We lose LRU, which in theory makes us cannibalize working sets randomly instead of by-usage. However, considering the speed of ReactOS paging, and the effects of canabalizing the WS in the first place, I doubt this is really a problem.
The main point of this is advantage #1 -- making used pages not be on any lists. This will allow us to almost 100% sync the PFN layouts, which will lead to the eventual negation of any temporary disavantages.
svn path=/trunk/; revision=45616
2010-02-19 00:46:35 +00:00
|
|
|
|
2020-10-06 19:44:01 +00:00
|
|
|
CODE_SEG("INIT")
|
2007-01-25 17:51:45 +00:00
|
|
|
BOOLEAN
|
2005-09-14 01:05:50 +00:00
|
|
|
NTAPI
|
2007-01-25 17:51:45 +00:00
|
|
|
MmInitSystem(IN ULONG Phase,
|
|
|
|
IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
2000-07-04 08:52:47 +00:00
|
|
|
{
|
2010-02-10 13:56:54 +00:00
|
|
|
extern MMPTE ValidKernelPte;
|
2009-07-27 02:13:19 +00:00
|
|
|
PMMPTE PointerPte;
|
2010-02-10 13:56:54 +00:00
|
|
|
MMPTE TempPte = ValidKernelPte;
|
2009-07-27 02:13:19 +00:00
|
|
|
PFN_NUMBER PageFrameNumber;
|
2019-01-18 21:11:43 +00:00
|
|
|
PLIST_ENTRY ListEntry;
|
|
|
|
PLDR_DATA_TABLE_ENTRY DataTableEntry;
|
2011-12-25 18:21:05 +00:00
|
|
|
|
2010-10-18 23:07:09 +00:00
|
|
|
/* Initialize the kernel address space */
|
|
|
|
ASSERT(Phase == 1);
|
[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
|
|
|
|
2020-10-23 14:16:51 +00:00
|
|
|
#ifdef NEWCC
|
[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
|
|
|
InitializeListHead(&MiSegmentList);
|
|
|
|
ExInitializeFastMutex(&MiGlobalPageOperation);
|
|
|
|
KeInitializeEvent(&MmWaitPageEvent, SynchronizationEvent, FALSE);
|
|
|
|
// Until we're fully demand paged, we can do things the old way through
|
|
|
|
// the balance manager
|
2020-10-23 14:16:51 +00:00
|
|
|
// CcInitView will override this...
|
[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
|
|
|
MmInitializeMemoryConsumer(MC_CACHE, MiRosTrimCache);
|
2020-10-23 14:16:51 +00:00
|
|
|
#else
|
|
|
|
KeInitializeEvent(&MmWaitPageEvent, SynchronizationEvent, FALSE);
|
|
|
|
#endif
|
[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
|
|
|
|
2010-10-18 23:07:09 +00:00
|
|
|
MmKernelAddressSpace = &PsIdleProcess->Vm;
|
|
|
|
|
|
|
|
/* Intialize system memory areas */
|
|
|
|
MiInitSystemMemoryAreas();
|
|
|
|
|
|
|
|
/* Dump the address space */
|
|
|
|
MiDbgDumpAddressSpace();
|
|
|
|
|
|
|
|
MmInitGlobalKernelPageDirectory();
|
|
|
|
MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory);
|
|
|
|
MmInitializeRmapList();
|
|
|
|
MmInitSectionImplementation();
|
|
|
|
MmInitPagingFile();
|
2011-12-25 18:21:05 +00:00
|
|
|
|
2010-10-18 23:07:09 +00:00
|
|
|
//
|
|
|
|
// Create a PTE to double-map the shared data section. We allocate it
|
|
|
|
// from paged pool so that we can't fault when trying to touch the PTE
|
|
|
|
// itself (to map it), since paged pool addresses will already be mapped
|
|
|
|
// by the fault handler.
|
|
|
|
//
|
|
|
|
MmSharedUserDataPte = ExAllocatePoolWithTag(PagedPool,
|
2014-10-05 06:33:34 +00:00
|
|
|
sizeof(MMPTE),
|
2016-01-05 19:53:07 +00:00
|
|
|
TAG_MM);
|
2010-10-18 23:07:09 +00:00
|
|
|
if (!MmSharedUserDataPte) return FALSE;
|
2011-12-25 18:21:05 +00:00
|
|
|
|
2010-10-18 23:07:09 +00:00
|
|
|
//
|
|
|
|
// Now get the PTE for shared data, and read the PFN that holds it
|
|
|
|
//
|
|
|
|
PointerPte = MiAddressToPte((PVOID)KI_USER_SHARED_DATA);
|
|
|
|
ASSERT(PointerPte->u.Hard.Valid == 1);
|
|
|
|
PageFrameNumber = PFN_FROM_PTE(PointerPte);
|
2011-12-25 18:21:05 +00:00
|
|
|
|
2010-10-18 23:07:09 +00:00
|
|
|
/* Build the PTE and write it */
|
|
|
|
MI_MAKE_HARDWARE_PTE_KERNEL(&TempPte,
|
|
|
|
PointerPte,
|
|
|
|
MM_READONLY,
|
|
|
|
PageFrameNumber);
|
|
|
|
*MmSharedUserDataPte = TempPte;
|
2011-12-25 18:21:05 +00:00
|
|
|
|
2013-11-20 23:50:42 +00:00
|
|
|
/* Initialize session working set support */
|
|
|
|
MiInitializeSessionWsSupport();
|
|
|
|
|
2012-02-06 17:41:49 +00:00
|
|
|
/* Setup session IDs */
|
|
|
|
MiInitializeSessionIds();
|
|
|
|
|
2010-10-18 23:07:09 +00:00
|
|
|
/* Setup the memory threshold events */
|
|
|
|
if (!MiInitializeMemoryEvents()) return FALSE;
|
2011-12-25 18:21:05 +00:00
|
|
|
|
2010-10-18 23:07:09 +00:00
|
|
|
/*
|
|
|
|
* Unmap low memory
|
|
|
|
*/
|
|
|
|
MiInitBalancerThread();
|
2011-12-25 18:21:05 +00:00
|
|
|
|
2010-10-18 23:07:09 +00:00
|
|
|
/* Initialize the balance set manager */
|
|
|
|
MmInitBsmThread();
|
2007-01-25 17:51:45 +00:00
|
|
|
|
2020-10-15 11:42:13 +00:00
|
|
|
/* Loop the boot loaded images (under lock) */
|
|
|
|
ExAcquireResourceExclusiveLite(&PsLoadedModuleResource, TRUE);
|
2019-01-18 21:11:43 +00:00
|
|
|
for (ListEntry = PsLoadedModuleList.Flink;
|
|
|
|
ListEntry != &PsLoadedModuleList;
|
|
|
|
ListEntry = ListEntry->Flink)
|
|
|
|
{
|
|
|
|
/* Get the data table entry */
|
|
|
|
DataTableEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
|
|
|
|
|
|
|
|
/* Set up the image protection */
|
|
|
|
MiWriteProtectSystemImage(DataTableEntry->DllBase);
|
|
|
|
}
|
2020-10-15 11:42:13 +00:00
|
|
|
ExReleaseResourceLite(&PsLoadedModuleResource);
|
2019-01-18 21:11:43 +00:00
|
|
|
|
2007-01-25 17:51:45 +00:00
|
|
|
return TRUE;
|
2000-07-04 08:52:47 +00:00
|
|
|
}
|
|
|
|
|