ReactOS 0.4.15-dev-7842-g558ab78
swapout.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 1998-2005 ReactOS Team (and the authors from the programmers section)
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 *
18 *
19 * PROJECT: ReactOS kernel
20 * FILE: ntoskrnl/cache/section/swapout.c
21 * PURPOSE: Consolidate fault handlers for sections
22 *
23 * PROGRAMMERS: Arty
24 * Rex Jolliff
25 * David Welch
26 * Eric Kohl
27 * Emanuele Aliberti
28 * Eugene Ingerman
29 * Casper Hornstrup
30 * KJK::Hyperion
31 * Guido de Jong
32 * Ge van Geldorp
33 * Royce Mitchell III
34 * Filip Navara
35 * Aleksey Bragin
36 * Jason Filby
37 * Thomas Weidenmueller
38 * Gunnar Andre' Dalsnes
39 * Mike Nordell
40 * Alex Ionescu
41 * Gregor Anich
42 * Steven Edwards
43 * Herve Poussineau
44 */
45
46/*
47
48This file implements page out infrastructure for cache type sections. This
49is implemented a little differently from the legacy mm because mapping in an
50address space and membership in a segment are considered separate.
51
52The general strategy here is to try to remove all mappings as gently as
53possible, then to remove the page entry from the section itself as a final
54step. If at any time during the page out operation, the page is mapped in
55a new address space by a competing thread, the operation will abort before
56the segment page is finally removed, and the page will be naturally faulted
57back into any address spaces required in the normal way.
58
59*/
60
61/* INCLUDES *****************************************************************/
62
63#include <ntoskrnl.h>
64#include "newmm.h"
65#define NDEBUG
66#include <debug.h>
67
68#define DPRINTC DPRINT
69
73
75
76/*
77
78MmWithdrawSectionPage removes a page entry from the section segment, replacing
79it with a wait entry. The caller must replace the wait entry with a 0, when
80any required writing is done. The wait entry must remain until the page is
81written to protect against cases where a fault brings a stale copy of the page
82back before writing is complete.
83
84*/
89 BOOLEAN *Dirty)
90{
92
93 DPRINT("MmWithdrawSectionPage(%p,%08x%08x,%p)\n",
94 Segment,
95 FileOffset->HighPart,
96 FileOffset->LowPart,
97 Dirty);
98
101
102 *Dirty = !!IS_DIRTY_SSE(Entry);
103
104 DPRINT("Withdraw %x (%x) of %wZ\n",
105 FileOffset->LowPart,
106 Entry,
107 Segment->FileObject ? &Segment->FileObject->FileName : NULL);
108
109 if (!Entry)
110 {
111 DPRINT("Stoeled!\n");
113 return 0;
114 }
115 else if (MM_IS_WAIT_PTE(Entry))
116 {
117 DPRINT("WAIT\n");
119 return MM_WAIT_ENTRY;
120 }
121 else if (Entry && !IS_SWAP_FROM_SSE(Entry))
122 {
123 DPRINT("Page %x\n", PFN_FROM_SSE(Entry));
124
125 *Dirty |= (Entry & 2);
126
129 MAKE_SWAP_SSE(MM_WAIT_ENTRY));
130
132 return PFN_FROM_SSE(Entry);
133 }
134 else
135 {
136 DPRINT1("SWAP ENTRY?! (%p:%08x%08x)\n",
137 Segment,
138 FileOffset->HighPart,
139 FileOffset->LowPart);
140
141 ASSERT(FALSE);
143 return 0;
144 }
145}
146
147/*
148
149This function determines whether the segment holds the very last reference to
150the page being considered and if so, writes it back or discards it as
151approriate. One small niggle here is that we might be holding the last
152reference to the section segment associated with this page. That happens
153when the segment is destroyed at the same time that an active swap operation
154is occurring, and all maps were already withdrawn. In that case, it's our
155responsiblity for finalizing the segment.
156
157Note that in the current code, WriteZero is always TRUE because the section
158always backs a file. In the ultimate form of this code, it also writes back
159pages without necessarily evicting them. In reactos' trunk, this is vestigal.
160
161*/
162
164NTAPI
168 BOOLEAN Dirty)
169{
171 BOOLEAN WriteZero = FALSE, WritePage = FALSE;
173
174 /* Bail early if the reference count isn't where we need it */
176 {
177 DPRINT1("Cannot page out locked page %x with ref count %lu\n",
178 Page,
180 return STATUS_UNSUCCESSFUL;
181 }
182
184 (void)InterlockedIncrementUL(&Segment->ReferenceCount);
185
186 if (Dirty)
187 {
188 DPRINT("Finalize (dirty) Segment %p Page %x\n", Segment, Page);
189 DPRINT("Segment->FileObject %p\n", Segment->FileObject);
190 DPRINT("Segment->Flags %x\n", Segment->Flags);
191
192 WriteZero = TRUE;
193 WritePage = TRUE;
194 }
195 else
196 {
197 WriteZero = TRUE;
198 }
199
200 DPRINT("Status %x\n", Status);
201
203
204 if (WritePage)
205 {
206 DPRINT("MiWriteBackPage(Segment %p FileObject %p Offset %x)\n",
207 Segment,
208 Segment->FileObject,
209 FileOffset->LowPart);
210
211 Status = MiWriteBackPage(Segment->FileObject,
213 PAGE_SIZE,
214 Page);
215 }
216
218
219 if (WriteZero && NT_SUCCESS(Status))
220 {
221 DPRINT("Setting page entry in segment %p:%x to swap %x\n",
222 Segment,
223 FileOffset->LowPart,
224 Swap);
225
228 Swap ? MAKE_SWAP_SSE(Swap) : 0);
229 }
230 else
231 {
232 DPRINT("Setting page entry in segment %p:%x to page %x\n",
233 Segment,
234 FileOffset->LowPart,
235 Page);
236
239 Page ? (Dirty ? DIRTY_SSE(MAKE_PFN_SSE(Page)) : MAKE_PFN_SSE(Page)) : 0);
240 }
241
242 if (NT_SUCCESS(Status))
243 {
244 DPRINT("Removing page %x for real\n", Page);
247 }
248
250
251 if (InterlockedDecrementUL(&Segment->ReferenceCount) == 0)
252 {
254 }
255
256 /* Note: Writing may evict the segment... Nothing is guaranteed from here down */
257 MiSetPageEvent(Segment, (ULONG_PTR)FileOffset->QuadPart);
258
259 DPRINT("Status %x\n", Status);
260 return Status;
261}
262
263/*
264
265The slightly misnamed MmPageOutCacheSection removes a page from an address
266space in the manner of fault handlers found in fault.c. In the ultimate form
267of the code, this is one of the function pointers stored in a memory area
268to control how pages in that memory area are managed.
269
270Also misleading is the call to MmReleasePageMemoryConsumer, which releases
271the reference held by this address space only. After all address spaces
272have had MmPageOutCacheSection succeed on them for the indicated page,
273then paging out of a cache page can continue.
274
275*/
276
278NTAPI
282 PBOOLEAN Dirty,
284{
286 PFN_NUMBER OurPage;
288 LARGE_INTEGER TotalOffset;
291
292 TotalOffset.QuadPart = (ULONG_PTR)PAddress -
294 MemoryArea->Data.SectionData.ViewOffset.QuadPart;
295
296 Segment = MemoryArea->Data.SectionData.Segment;
297
300
303
304 if (MmIsPageSwapEntry(Process, PAddress))
305 {
306 SWAPENTRY SwapEntry;
307 MmGetPageFileMapping(Process, PAddress, &SwapEntry);
309 return SwapEntry == MM_WAIT_ENTRY ? STATUS_SUCCESS + 1 : STATUS_UNSUCCESSFUL;
310 }
311
313 MmDeleteVirtualMapping(Process, Address, Dirty, &OurPage);
314 ASSERT(OurPage == Required->Page[0]);
315
316 /* Note: this releases the reference held by this address space only. */
317 MmReleasePageMemoryConsumer(MC_CACHE, Required->Page[0]);
318
320 MiSetPageEvent(Process, Address);
321 return STATUS_SUCCESS;
322}
323
324/*
325
326This function is called by rmap when spare pages are needed by the blancer.
327It attempts first to release the page from every address space in which it
328appears, and, after a final check that no competing thread has mapped the
329page again, uses MmFinalizeSectionPageOut to completely evict the page. If
330that's successful, then a suitable non-page map will be left in the segment
331page table, otherwise, the original page is replaced in the section page
332map. Failure may result from a variety of conditions, but always leaves
333the page mapped.
334
335This code is like the other fault handlers, in that MmPageOutCacheSection has
336the option of returning either STATUS_SUCCESS + 1 to wait for a wait entry
337to disppear or to use the blocking callout facility by returning
338STATUS_MORE_PROCESSING_REQUIRED and placing a pointer to a function from
339reqtools.c in the MM_REQUIRED_RESOURCES struct.
340
341*/
342
344NTAPI
346{
347 BOOLEAN ProcRef = FALSE, PageDirty;
348 PFN_NUMBER SectionPage = 0;
354 BOOLEAN Dirty = FALSE;
359
360 DPRINTC("Page out %x (ref ct %x)\n", Page, MmGetReferenceCountPageWithoutLock(Page));
361
364 {
365 DPRINTC("Withdrawing page (%x) %p:%x\n",
366 Page,
367 Segment,
368 FileOffset.LowPart);
369
370 SectionPage = MmWithdrawSectionPage(Segment, &FileOffset, &Dirty);
371 DPRINTC("SectionPage %x\n", SectionPage);
372
373 if (SectionPage == MM_WAIT_ENTRY || SectionPage == 0)
374 {
375 DPRINT1("In progress page out %x\n", SectionPage);
377 return STATUS_UNSUCCESSFUL;
378 }
379 else
380 {
381 ASSERT(SectionPage == Page);
382 }
383 Resources.State = Dirty ? 1 : 0;
384 }
385 else
386 {
387 DPRINT("No segment association for %x\n", Page);
388 }
389
390 Dirty = MmIsDirtyPageRmap(Page);
391
392 DPRINTC("Trying to unmap all instances of %x\n", Page);
395
396 // Entry and Segment might be null here in the case that the page
397 // is new and is in the process of being swapped in
398 if (!entry && !Segment)
399 {
401 DPRINT1("Page %x is in transit\n", Page);
403 goto bail;
404 }
405
406 while (entry != NULL && NT_SUCCESS(Status))
407 {
408 Process = entry->Process;
409 Address = entry->Address;
410
411 DPRINTC("Process %p Address %p Page %x\n", Process, Address, Page);
412
414 {
415 entry = entry->Next;
416 continue;
417 }
418
420 {
421 /* Make sure we don't try to page out part of an exiting process */
423 {
424 DPRINT("bail\n");
426 goto bail;
427 }
429 ProcRef = TRUE;
430 AddressSpace = &Process->Vm;
431 }
432 else
433 {
435 }
437
439
440 if ((((ULONG_PTR)Address) & 0xFFF) != 0)
441 {
442 KeBugCheck(MEMORY_MANAGEMENT);
443 }
444
445 do
446 {
448
451 {
454 DPRINTC("bail\n");
455 goto bail;
456 }
457
458 DPRINTC("Type %x (%p -> %p)\n",
462
463 Resources.DoAcquisition = NULL;
464 Resources.Page[0] = Page;
465
467
468 DPRINT("%p:%p, page %x %x\n",
469 Process,
470 Address,
471 Page,
472 Resources.Page[0]);
473
475
478 Address,
479 &PageDirty,
480 &Resources);
481
482 Dirty |= PageDirty;
483 DPRINT("%x\n", Status);
484
486
488
489 if (Status == STATUS_SUCCESS + 1)
490 {
491 // Wait page ... the other guy has it, so we'll just fail for now
492 DPRINT1("Wait entry ... can't continue\n");
494 goto bail;
495 }
497 {
498 DPRINTC("DoAcquisition %p\n", Resources.DoAcquisition);
499
500 Status = Resources.DoAcquisition(AddressSpace,
502 &Resources);
503
504 DPRINTC("Status %x\n", Status);
505 if (!NT_SUCCESS(Status))
506 {
507 DPRINT1("bail\n");
508 goto bail;
509 }
510 else
511 {
513 }
514 }
515 }
517
518 if (ProcRef)
519 {
521 ProcRef = FALSE;
522 }
523
527
528 DPRINTC("Entry %p\n", entry);
529 }
530
532
533bail:
534 DPRINTC("BAIL %x\n", Status);
535
536 if (Segment)
537 {
538 ULONG RefCount;
539
540 DPRINTC("About to finalize section page %x (%p:%x) Status %x %s\n",
541 Page,
542 Segment,
543 FileOffset.LowPart,
544 Status,
545 Dirty ? "dirty" : "clean");
546
547 if (!NT_SUCCESS(Status) ||
549 &FileOffset,
550 Page,
551 Dirty)))
552 {
553 DPRINTC("Failed to page out %x, replacing %x at %x in segment %x\n",
554 SectionPage,
555 FileOffset.LowPart,
556 Segment);
557
559
561 &FileOffset,
563
565 }
566
567 /* Alas, we had the last reference */
568 if ((RefCount = InterlockedDecrementUL(&Segment->ReferenceCount)) == 0)
570 }
571
572 if (ProcRef)
573 {
574 DPRINTC("Dereferencing process...\n");
576 }
577
579
580 DPRINTC("%s %x %x\n",
581 NT_SUCCESS(Status) ? "Evicted" : "Spared",
582 Page,
583 Status);
584
586}
587
588ULONG
589NTAPI
592{
594 ULONG Result = 0, i, j;
598
600
601 for (i = 0; i < RtlNumberGenericTableElements(&Segment->PageTable); i++) {
602
604 i);
605
606 ASSERT(Element);
607
608 Offset = Element->FileOffset;
609 for (j = 0; j < ENTRIES_PER_ELEMENT; j++, Offset.QuadPart += PAGE_SIZE) {
611 if (Entry && !IS_SWAP_FROM_SSE(Entry)) {
615 if (NT_SUCCESS(Status))
616 Result++;
618 }
619 }
620 }
621
623
624 return Result;
625}
626
628
629// Interact with legacy balance manager for now
630// This can fall away when our section implementation supports
631// demand paging properly
635 PULONG NrFreed)
636{
637 ULONG Freed;
640 *NrFreed = 0;
641
642 DPRINT1("Need to trim %lu cache pages\n", Target);
644 *NrFreed < Target && Entry != &MiSegmentList;
645 Entry = Entry->Flink) {
647 /* Defer to MM to try recovering pages from it */
649 *NrFreed += Freed;
650 }
651 DPRINT1("Evicted %lu cache pages\n", Target);
652
653 if (!IsListEmpty(&MiSegmentList)) {
657 }
658
659 return STATUS_SUCCESS;
660}
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1431
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ULONG_PTR
Definition: config.h:101
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define InterlockedDecrementUL(Addend)
Definition: ex.h:1524
#define InterlockedIncrementUL(Addend)
Definition: ex.h:1527
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
Status
Definition: gdiplustypes.h:25
#define Swap(a, b)
Definition: geom.c:201
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
uint32_t entry
Definition: isohybrid.c:63
#define ASSERT(a)
Definition: mode.c:44
#define PageDirty(page)
Definition: module.h:617
ULONG MmGetReferenceCountPageWithoutLock(PFN_NUMBER Page)
Definition: newcc.h:165
VOID NTAPI MmFinalizeSegment(PMM_SECTION_SEGMENT Segment)
#define MiWriteBackPage(F, O, L, P)
Definition: newmm.h:156
_In_ PMEMORY_AREA _In_ PVOID _In_ BOOLEAN _Inout_ PMM_REQUIRED_RESOURCES Required
Definition: newmm.h:210
_In_ PMEMORY_AREA MemoryArea
Definition: newmm.h:207
#define ENTRIES_PER_ELEMENT
Definition: newmm.h:21
#define DBG_UNREFERENCED_LOCAL_VARIABLE(L)
Definition: ntbasedef.h:319
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define MmSystemRangeStart
Definition: mm.h:32
#define MmGetPageEntrySectionSegment(S, O)
Definition: mm.h:1602
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1691
#define DIRTY_SSE(E)
Definition: mm.h:1375
struct _MM_RMAP_ENTRY *NTAPI MmGetRmapListHeadPage(PFN_NUMBER Page)
Definition: freelist.c:458
VOID NTAPI MmGetPageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY *SwapEntry)
Definition: page.c:299
#define MmLockSectionSegment(x)
Definition: mm.h:1397
#define MmSetPageEntrySectionSegment(S, O, E)
Definition: mm.h:1600
#define MmUnlockSectionSegment(x)
Definition: mm.h:1405
BOOLEAN NTAPI MmIsPageSwapEntry(struct _EPROCESS *Process, PVOID Address)
#define RMAP_IS_SEGMENT(x)
Definition: mm.h:940
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1306
PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress(PMMSUPPORT AddressSpace, PVOID Address)
Definition: marea.c:60
#define IS_DIRTY_SSE(E)
Definition: mm.h:1377
#define MAKE_PFN_SSE(P)
Definition: mm.h:1372
#define MAKE_SWAP_SSE(S)
Definition: mm.h:1374
ULONG_PTR SWAPENTRY
Definition: mm.h:57
#define MA_GetEndingAddress(_MemoryArea)
Definition: mm.h:245
PFN_NUMBER NTAPI MmGetPfnForProcess(struct _EPROCESS *Process, PVOID Address)
#define MA_GetStartingAddress(_MemoryArea)
Definition: mm.h:244
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1704
FORCEINLINE PEPROCESS MmGetAddressSpaceOwner(IN PMMSUPPORT AddressSpace)
Definition: mm.h:1711
VOID NTAPI MmSetSavedSwapEntryPage(PFN_NUMBER Page, SWAPENTRY SavedSwapEntry)
Definition: freelist.c:483
#define PFN_FROM_SSE(E)
Definition: mm.h:1368
SWAPENTRY NTAPI MmGetSavedSwapEntryPage(PFN_NUMBER Page)
Definition: freelist.c:499
VOID NTAPI MmDeleteRmap(PFN_NUMBER Page, struct _EPROCESS *Process, PVOID Address)
#define MM_ROUND_DOWN(x, s)
Definition: mm.h:131
#define MM_IS_WAIT_PTE(E)
Definition: mm.h:1370
#define IS_SWAP_FROM_SSE(E)
Definition: mm.h:1369
NTSTATUS NTAPI MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page)
Definition: balance.c:72
FORCEINLINE PMMSUPPORT MmGetKernelAddressSpace(VOID)
Definition: mm.h:1726
#define STATUS_MM_RESTART_OPERATION
Definition: mm.h:104
VOID NTAPI MmDeleteVirtualMapping(IN PEPROCESS Process, IN PVOID Address, OUT PBOOLEAN WasDirty, OUT PPFN_NUMBER Page)
Definition: page.c:177
static WCHAR Address[46]
Definition: ping.c:68
BOOLEAN NTAPI PspIsProcessExiting(IN PEPROCESS Process)
Definition: kill.c:1068
ULONG PFN_NUMBER
Definition: ke.h:9
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
PMM_SECTION_SEGMENT NTAPI MmGetSectionAssociation(PFN_NUMBER Page, PLARGE_INTEGER Offset)
Definition: sptab.c:374
base of all file and directory entries
Definition: entries.h:83
LARGE_INTEGER FileOffset
Definition: newmm.h:27
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
struct _MEMORY_AREA::@1787 SectionData
BOOLEAN DeleteInProgress
Definition: mm.h:253
ULONG Type
Definition: mm.h:251
Definition: mm.h:266
static VOID WritePage(PMEM_HOOK Hook, ULONG Address, PVOID Buffer, ULONG Size)
Definition: memory.c:129
FAST_MUTEX MiGlobalPageOperation
Definition: swapout.c:74
PMMWSL MmWorkingSetList
Definition: wslist.cpp:19
NTSTATUS MiRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed)
Definition: swapout.c:633
FAST_MUTEX RmapListLock
NTSTATUS NTAPI MmFinalizeSectionPageOut(PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER FileOffset, PFN_NUMBER Page, BOOLEAN Dirty)
Definition: swapout.c:165
#define DPRINTC
Definition: swapout.c:68
ULONG NTAPI MiCacheEvictPages(PMM_SECTION_SEGMENT Segment, ULONG Target)
Definition: swapout.c:590
PFN_NUMBER NTAPI MmWithdrawSectionPage(PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER FileOffset, BOOLEAN *Dirty)
Definition: swapout.c:87
NTSTATUS NTAPI MmpPageOutPhysicalAddress(PFN_NUMBER Page)
Definition: swapout.c:345
NTSTATUS NTAPI MmPageOutCacheSection(PMMSUPPORT AddressSpace, MEMORY_AREA *MemoryArea, PVOID Address, PBOOLEAN Dirty, PMM_REQUIRED_RESOURCES Required)
Definition: swapout.c:279
LIST_ENTRY MiSegmentList
Definition: data.c:86
KEVENT MmWaitPageEvent
Definition: fault.c:461
uint32_t * PULONG
Definition: typedefs.h:59
unsigned char * PBOOLEAN
Definition: typedefs.h:53
#define NTAPI
Definition: typedefs.h:36
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
LONGLONG QuadPart
Definition: typedefs.h:114
_In_ WDFINTERRUPT _In_ WDF_INTERRUPT_POLICY _In_ WDF_INTERRUPT_PRIORITY Priority
Definition: wdfinterrupt.h:655
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
FAST_MUTEX
Definition: extypes.h:17
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2274
#define ObDereferenceObject
Definition: obfuncs.h:203
#define ObReferenceObject
Definition: obfuncs.h:204
_Must_inspect_result_ NTSYSAPI PVOID NTAPI RtlGetElementGenericTable(_In_ PRTL_GENERIC_TABLE Table, _In_ ULONG I)
NTSYSAPI ULONG NTAPI RtlNumberGenericTableElements(_In_ PRTL_GENERIC_TABLE Table)