ReactOS  0.4.14-dev-98-gb0d4763
swapout.c File Reference
#include <ntoskrnl.h>
#include "newmm.h"
#include <debug.h>
Include dependency graph for swapout.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define DPRINTC   DPRINT
 

Functions

PFN_NUMBER NTAPI MmWithdrawSectionPage (PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER FileOffset, BOOLEAN *Dirty)
 
NTSTATUS NTAPI MmFinalizeSectionPageOut (PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER FileOffset, PFN_NUMBER Page, BOOLEAN Dirty)
 
NTSTATUS NTAPI MmPageOutCacheSection (PMMSUPPORT AddressSpace, MEMORY_AREA *MemoryArea, PVOID Address, PBOOLEAN Dirty, PMM_REQUIRED_RESOURCES Required)
 
NTSTATUS NTAPI MmpPageOutPhysicalAddress (PFN_NUMBER Page)
 
ULONG NTAPI MiCacheEvictPages (PMM_SECTION_SEGMENT Segment, ULONG Target)
 
NTSTATUS MiRosTrimCache (ULONG Target, ULONG Priority, PULONG NrFreed)
 

Variables

KEVENT MmWaitPageEvent
 
FAST_MUTEX RmapListLock
 
PMMWSL MmWorkingSetList
 
FAST_MUTEX MiGlobalPageOperation
 
LIST_ENTRY MiSegmentList
 

Macro Definition Documentation

◆ DPRINTC

#define DPRINTC   DPRINT

Definition at line 68 of file swapout.c.

◆ NDEBUG

#define NDEBUG

Definition at line 65 of file swapout.c.

Function Documentation

◆ MiCacheEvictPages()

ULONG NTAPI MiCacheEvictPages ( PMM_SECTION_SEGMENT  Segment,
ULONG  Target 
)

Definition at line 590 of file swapout.c.

592 {
594  ULONG Result = 0, i, j;
596  PFN_NUMBER Page;
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)) {
612  Page = PFN_FROM_SSE(Entry);
615  if (NT_SUCCESS(Status))
616  Result++;
618  }
619  }
620  }
621 
623 
624  return Result;
625 }
struct _Entry Entry
Definition: kefuncs.h:640
#define PFN_FROM_SSE(E)
Definition: newmm.h:7
NTSYSAPI ULONG NTAPI RtlNumberGenericTableElements(_In_ PRTL_GENERIC_TABLE Table)
LONG NTSTATUS
Definition: precomp.h:26
uint32_t ULONG_PTR
Definition: typedefs.h:63
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
ULONG PFN_NUMBER
Definition: ke.h:8
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_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:426
_Inout_ PVOID Segment
Definition: exfuncs.h:893
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
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_Must_inspect_result_ NTSYSAPI PVOID NTAPI RtlGetElementGenericTable(_In_ PRTL_GENERIC_TABLE Table, _In_ ULONG I)
LARGE_INTEGER FileOffset
Definition: newmm.h:55
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define IS_SWAP_FROM_SSE(E)
Definition: newmm.h:8
Status
Definition: gdiplustypes.h:24
#define MmLockSectionSegment(x)
Definition: newmm.h:276
unsigned int ULONG
Definition: retypes.h:1
#define MmUnlockSectionSegment(x)
Definition: newmm.h:284
base of all file and directory entries
Definition: entries.h:82
#define MmGetPageEntrySectionSegment(S, O)
Definition: newmm.h:143
NTSTATUS NTAPI MmpPageOutPhysicalAddress(PFN_NUMBER Page)
Definition: swapout.c:345
#define ENTRIES_PER_ELEMENT
Definition: newmm.h:49

Referenced by MiRosTrimCache().

◆ MiRosTrimCache()

NTSTATUS MiRosTrimCache ( ULONG  Target,
ULONG  Priority,
PULONG  NrFreed 
)

Definition at line 633 of file swapout.c.

636 {
637  ULONG Freed;
640  *NrFreed = 0;
641 
642  DPRINT1("Need to trim %lu cache pages\n", Target);
643  for (Entry = MiSegmentList.Flink;
644  *NrFreed < Target && Entry != &MiSegmentList;
645  Entry = Entry->Flink) {
647  /* Defer to MM to try recovering pages from it */
648  Freed = MiCacheEvictPages(Segment, Target);
649  *NrFreed += Freed;
650  }
651  DPRINT1("Evicted %lu cache pages\n", Target);
652 
653  if (!IsListEmpty(&MiSegmentList)) {
657  }
658 
659  return STATUS_SUCCESS;
660 }
struct _Entry Entry
Definition: kefuncs.h:640
#define InsertTailList(ListHead, Entry)
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
_Inout_ PVOID Segment
Definition: exfuncs.h:893
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
_Must_inspect_result_ typedef _In_ ULONG _In_ BOOLEAN Target
Definition: iotypes.h:1068
LIST_ENTRY MiSegmentList
Definition: data.c:86
Definition: typedefs.h:117
ULONG NTAPI MiCacheEvictPages(PMM_SECTION_SEGMENT Segment, ULONG Target)
Definition: swapout.c:590
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
return STATUS_SUCCESS
Definition: btrfs.c:2966
base of all file and directory entries
Definition: entries.h:82

Referenced by CcShutdownSystem(), and MmInitSystem().

◆ MmFinalizeSectionPageOut()

NTSTATUS NTAPI MmFinalizeSectionPageOut ( PMM_SECTION_SEGMENT  Segment,
PLARGE_INTEGER  FileOffset,
PFN_NUMBER  Page,
BOOLEAN  Dirty 
)

Definition at line 165 of file swapout.c.

169 {
171  BOOLEAN WriteZero = FALSE, WritePage = FALSE;
173 
174  /* Bail early if the reference count isn't where we need it */
175  if (MmGetReferenceCountPage(Page) != 1)
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,
212  FileOffset,
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 
227  FileOffset,
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 
238  FileOffset,
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);
245  MmSetSavedSwapEntryPage(Page, 0);
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 */
258 
259  DPRINT("Status %x\n", Status);
260  return Status;
261 }
#define MmSetPageEntrySectionSegment(S, O, E)
Definition: newmm.h:141
#define TRUE
Definition: types.h:120
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
#define MiSetPageEvent(Process, Address)
Definition: newmm.h:43
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page)
Definition: balance.c:97
#define MAKE_PFN_SSE(P)
Definition: newmm.h:11
uint32_t ULONG_PTR
Definition: typedefs.h:63
VOID NTAPI MmFinalizeSegment(PMM_SECTION_SEGMENT Segment)
Definition: data.c:271
unsigned char BOOLEAN
void DPRINT(...)
Definition: polytest.cpp:61
_Inout_ PVOID Segment
Definition: exfuncs.h:893
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG NTAPI MmGetReferenceCountPage(PFN_NUMBER Page)
Definition: freelist.c:509
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
static VOID WritePage(PMEM_HOOK Hook, ULONG Address, PVOID Buffer, ULONG Size)
Definition: memory.c:126
#define Swap(a, b)
Definition: geom.c:201
#define InterlockedDecrementUL(Addend)
Definition: ex.h:1510
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Status
Definition: gdiplustypes.h:24
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:151
#define InterlockedIncrementUL(Addend)
Definition: ex.h:1513
ULONG_PTR SWAPENTRY
Definition: mm.h:47
#define DPRINT1
Definition: precomp.h:8
#define MmLockSectionSegment(x)
Definition: newmm.h:276
VOID NTAPI MmSetSavedSwapEntryPage(PFN_NUMBER Page, SWAPENTRY SavedSwapEntry)
Definition: freelist.c:454
#define MC_CACHE
Definition: mm.h:93
#define DIRTY_SSE(E)
Definition: newmm.h:14
#define MmUnlockSectionSegment(x)
Definition: newmm.h:284
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define MAKE_SWAP_SSE(S)
Definition: newmm.h:13
SWAPENTRY NTAPI MmGetSavedSwapEntryPage(PFN_NUMBER Page)
Definition: freelist.c:470
#define MiWriteBackPage(F, O, L, P)
Definition: newmm.h:209

Referenced by MmpPageOutPhysicalAddress().

◆ MmPageOutCacheSection()

NTSTATUS NTAPI MmPageOutCacheSection ( PMMSUPPORT  AddressSpace,
MEMORY_AREA MemoryArea,
PVOID  Address,
PBOOLEAN  Dirty,
PMM_REQUIRED_RESOURCES  Required 
)

Definition at line 279 of file swapout.c.

284 {
286  PFN_NUMBER OurPage;
288  LARGE_INTEGER TotalOffset;
290  PVOID PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
291 
292  TotalOffset.QuadPart = (ULONG_PTR)PAddress -
294  MemoryArea->Data.SectionData.ViewOffset.QuadPart;
295 
296  Segment = MemoryArea->Data.SectionData.Segment;
297 
300 
301  Entry = MmGetPageEntrySectionSegment(Segment, &TotalOffset);
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 
312  MmDeleteRmap(Required->Page[0], Process, Address);
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. */
318 
321  return STATUS_SUCCESS;
322 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define MiSetPageEvent(Process, Address)
Definition: newmm.h:43
struct _Entry Entry
Definition: kefuncs.h:640
VOID NTAPI MmDeleteRmap(PFN_NUMBER Page, struct _EPROCESS *Process, PVOID Address)
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2268
NTSTATUS NTAPI MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page)
Definition: balance.c:97
#define MM_WAIT_ENTRY
Definition: mm.h:152
uint32_t ULONG_PTR
Definition: typedefs.h:63
ULONG PFN_NUMBER
Definition: ke.h:8
union _MEMORY_AREA::@1729 Data
static WCHAR Address[46]
Definition: ping.c:68
VOID NTAPI MmDeleteVirtualMapping(struct _EPROCESS *Process, PVOID Address, BOOLEAN *WasDirty, PPFN_NUMBER Page)
VOID NTAPI MmGetPageFileMapping(struct _EPROCESS *Process, PVOID Address, SWAPENTRY *SwapEntry)
_Inout_ PVOID Segment
Definition: exfuncs.h:893
#define DBG_UNREFERENCED_LOCAL_VARIABLE(L)
Definition: ntbasedef.h:326
BOOLEAN NTAPI MmIsPageSwapEntry(struct _EPROCESS *Process, PVOID Address)
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define MM_ROUND_DOWN(x, s)
Definition: mm.h:111
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define MA_GetStartingAddress(_MemoryArea)
Definition: mm.h:207
ULONG_PTR SWAPENTRY
Definition: mm.h:47
FORCEINLINE PEPROCESS MmGetAddressSpaceOwner(IN PMMSUPPORT AddressSpace)
Definition: mm.h:1438
#define MmLockSectionSegment(x)
Definition: newmm.h:276
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define MC_CACHE
Definition: mm.h:93
#define ULONG_PTR
Definition: config.h:101
struct _MEMORY_AREA::@1729::@1730 SectionData
struct _MEMORY_AREA struct _MM_REQUIRED_RESOURCES * Required
Definition: newmm.h:66
#define MmUnlockSectionSegment(x)
Definition: newmm.h:284
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define APC_LEVEL
Definition: env_spec_w32.h:695
base of all file and directory entries
Definition: entries.h:82
#define MmGetPageEntrySectionSegment(S, O)
Definition: newmm.h:143
LONGLONG QuadPart
Definition: typedefs.h:112

Referenced by MmpPageOutPhysicalAddress().

◆ MmpPageOutPhysicalAddress()

NTSTATUS NTAPI MmpPageOutPhysicalAddress ( PFN_NUMBER  Page)

Definition at line 345 of file swapout.c.

346 {
347  BOOLEAN ProcRef = FALSE, PageDirty;
348  PFN_NUMBER SectionPage = 0;
354  BOOLEAN Dirty = FALSE;
355  PVOID Address = NULL;
359 
360  DPRINTC("Page out %x (ref ct %x)\n", Page, MmGetReferenceCountPage(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 
438  RtlZeroMemory(&Resources, sizeof(Resources));
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",
459  MemoryArea->Type,
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 
474  PageDirty = FALSE;
475 
477  MemoryArea,
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,
501  MemoryArea,
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 
533 bail:
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,
562  Dirty ? MAKE_PFN_SSE(Page) : DIRTY_SSE(MAKE_PFN_SSE(Page)));
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 }
#define MmSetPageEntrySectionSegment(S, O, E)
Definition: newmm.h:141
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define PageDirty(page)
Definition: module.h:607
#define TRUE
Definition: types.h:120
#define DPRINTC
Definition: swapout.c:68
ULONG Type
Definition: mm.h:214
NTSTATUS NTAPI MmFinalizeSectionPageOut(PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER FileOffset, PFN_NUMBER Page, BOOLEAN Dirty)
Definition: swapout.c:165
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:63
#define STATUS_MM_RESTART_OPERATION
Definition: mm.h:80
struct _MM_RMAP_ENTRY *NTAPI MmGetRmapListHeadPage(PFN_NUMBER Page)
Definition: freelist.c:427
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2268
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1431
LONG NTSTATUS
Definition: precomp.h:26
#define MAKE_PFN_SSE(P)
Definition: newmm.h:11
BOOLEAN NTAPI MmIsDirtyPageRmap(PFN_NUMBER Page)
Definition: rmap.c:239
#define MM_WAIT_ENTRY
Definition: mm.h:152
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress(PMMSUPPORT AddressSpace, PVOID Address)
Definition: marea.c:60
FAST_MUTEX RmapListLock
Definition: rmap.c:26
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
uint32_t ULONG_PTR
Definition: typedefs.h:63
VOID NTAPI MmFinalizeSegment(PMM_SECTION_SEGMENT Segment)
Definition: data.c:271
ULONG PFN_NUMBER
Definition: ke.h:8
NTSTATUS NTAPI MmPageOutCacheSection(PMMSUPPORT AddressSpace, MEMORY_AREA *MemoryArea, PVOID Address, PBOOLEAN Dirty, PMM_REQUIRED_RESOURCES Required)
Definition: swapout.c:279
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
static WCHAR Address[46]
Definition: ping.c:68
void DPRINT(...)
Definition: polytest.cpp:61
VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1507
PMM_SECTION_SEGMENT NTAPI MmGetSectionAssociation(PFN_NUMBER Page, PLARGE_INTEGER Offset)
Definition: sptab.c:331
_Inout_ PVOID Segment
Definition: exfuncs.h:893
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
BOOLEAN DeleteInProgress
Definition: mm.h:217
#define MA_GetEndingAddress(_MemoryArea)
Definition: mm.h:208
BOOLEAN NTAPI PspIsProcessExiting(IN PEPROCESS Process)
Definition: kill.c:1067
ULONG NTAPI MmGetReferenceCountPage(PFN_NUMBER Page)
Definition: freelist.c:509
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
uint32_t entry
Definition: isohybrid.c:63
#define InterlockedDecrementUL(Addend)
Definition: ex.h:1510
#define MA_GetStartingAddress(_MemoryArea)
Definition: mm.h:207
Status
Definition: gdiplustypes.h:24
FORCEINLINE PMMSUPPORT MmGetKernelAddressSpace(VOID)
Definition: mm.h:1453
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
PFN_NUMBER NTAPI MmGetPfnForProcess(struct _EPROCESS *Process, PVOID Address)
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:151
#define DPRINT1
Definition: precomp.h:8
#define MmLockSectionSegment(x)
Definition: newmm.h:276
#define MM_IS_WAIT_PTE(E)
Definition: newmm.h:9
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define ObReferenceObject
Definition: obfuncs.h:204
#define DIRTY_SSE(E)
Definition: newmm.h:14
unsigned int ULONG
Definition: retypes.h:1
Definition: mm.h:236
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define MmUnlockSectionSegment(x)
Definition: newmm.h:284
#define RMAP_IS_SEGMENT(x)
Definition: newmm.h:25
FAST_MUTEX MiGlobalPageOperation
Definition: swapout.c:74
return STATUS_SUCCESS
Definition: btrfs.c:2966
struct _MEMORY_AREA * MemoryArea
Definition: newmm.h:65
#define APC_LEVEL
Definition: env_spec_w32.h:695
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1424
#define MmSystemRangeStart
Definition: mm.h:32
PFN_NUMBER NTAPI MmWithdrawSectionPage(PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER FileOffset, BOOLEAN *Dirty)
Definition: swapout.c:87

Referenced by MiCacheEvictPages(), and MmPageOutPhysicalAddress().

◆ MmWithdrawSectionPage()

PFN_NUMBER NTAPI MmWithdrawSectionPage ( PMM_SECTION_SEGMENT  Segment,
PLARGE_INTEGER  FileOffset,
BOOLEAN Dirty 
)

Definition at line 87 of file swapout.c.

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 
128  FileOffset,
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 }
#define MmSetPageEntrySectionSegment(S, O, E)
Definition: newmm.h:141
#define IS_DIRTY_SSE(E)
Definition: newmm.h:16
struct _Entry Entry
Definition: kefuncs.h:640
#define PFN_FROM_SSE(E)
Definition: newmm.h:7
#define MM_WAIT_ENTRY
Definition: mm.h:152
uint32_t ULONG_PTR
Definition: typedefs.h:63
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
_Inout_ PVOID Segment
Definition: exfuncs.h:893
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define IS_SWAP_FROM_SSE(E)
Definition: newmm.h:8
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:151
#define DPRINT1
Definition: precomp.h:8
#define MmLockSectionSegment(x)
Definition: newmm.h:276
#define MM_IS_WAIT_PTE(E)
Definition: newmm.h:9
#define MmUnlockSectionSegment(x)
Definition: newmm.h:284
#define MAKE_SWAP_SSE(S)
Definition: newmm.h:13
base of all file and directory entries
Definition: entries.h:82
#define MmGetPageEntrySectionSegment(S, O)
Definition: newmm.h:143

Referenced by MmpPageOutPhysicalAddress().

Variable Documentation

◆ MiGlobalPageOperation

FAST_MUTEX MiGlobalPageOperation

Definition at line 74 of file swapout.c.

Referenced by MmInitSystem(), and MmpPageOutPhysicalAddress().

◆ MiSegmentList

LIST_ENTRY MiSegmentList

Definition at line 86 of file data.c.

Referenced by MiRosTrimCache().

◆ MmWaitPageEvent

KEVENT MmWaitPageEvent

◆ MmWorkingSetList

PMMWSL MmWorkingSetList

Definition at line 21 of file procsup.c.

◆ RmapListLock