ReactOS  0.4.15-dev-499-g1f31905
balance.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
#include "ARM3/miarm.h"
Include dependency graph for balance.c:

Go to the source code of this file.

Classes

struct  _MM_ALLOCATION_REQUEST
 

Macros

#define NDEBUG
 

Typedefs

typedef struct _MM_ALLOCATION_REQUEST MM_ALLOCATION_REQUEST
 
typedef struct _MM_ALLOCATION_REQUESTPMM_ALLOCATION_REQUEST
 

Functions

INIT_FUNCTION VOID NTAPI MmInitializeBalancer (ULONG NrAvailablePages, ULONG NrSystemPages)
 
INIT_FUNCTION VOID NTAPI MmInitializeMemoryConsumer (ULONG Consumer, NTSTATUS(*Trim)(ULONG Target, ULONG Priority, PULONG NrFreed))
 
VOID NTAPI MiZeroPhysicalPage (IN PFN_NUMBER PageFrameIndex)
 
NTSTATUS NTAPI MmReleasePageMemoryConsumer (ULONG Consumer, PFN_NUMBER Page)
 
ULONG NTAPI MiTrimMemoryConsumer (ULONG Consumer, ULONG InitialTarget)
 
NTSTATUS MmTrimUserMemory (ULONG Target, ULONG Priority, PULONG NrFreedPages)
 
static BOOLEAN MiIsBalancerThread (VOID)
 
VOID NTAPI MmRebalanceMemoryConsumers (VOID)
 
NTSTATUS NTAPI MmRequestPageMemoryConsumer (ULONG Consumer, BOOLEAN CanWait, PPFN_NUMBER AllocatedPage)
 
VOID NTAPI MiBalancerThread (PVOID Unused)
 
BOOLEAN MmRosNotifyAvailablePage (PFN_NUMBER Page)
 
INIT_FUNCTION VOID NTAPI MiInitBalancerThread (VOID)
 

Variables

MM_MEMORY_CONSUMER MiMemoryConsumers [MC_MAXIMUM]
 
static ULONG MiMinimumAvailablePages
 
static ULONG MiNrTotalPages
 
static LIST_ENTRY AllocationListHead
 
static KSPIN_LOCK AllocationListLock
 
static ULONG MiMinimumPagesPerRun
 
static CLIENT_ID MiBalancerThreadId
 
static HANDLE MiBalancerThreadHandle = NULL
 
static KEVENT MiBalancerEvent
 
static KTIMER MiBalancerTimer
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 14 of file balance.c.

Typedef Documentation

◆ MM_ALLOCATION_REQUEST

◆ PMM_ALLOCATION_REQUEST

Function Documentation

◆ MiBalancerThread()

VOID NTAPI MiBalancerThread ( PVOID  Unused)

Definition at line 328 of file balance.c.

329 {
330  PVOID WaitObjects[2];
332  ULONG i;
333 
334  WaitObjects[0] = &MiBalancerEvent;
335  WaitObjects[1] = &MiBalancerTimer;
336 
337  while (1)
338  {
340  WaitObjects,
341  WaitAny,
342  Executive,
343  KernelMode,
344  FALSE,
345  NULL,
346  NULL);
347 
349  {
350  ULONG InitialTarget = 0;
351 
352 #if (_MI_PAGING_LEVELS == 2)
353  if (!MiIsBalancerThread())
354  {
355  /* Clean up the unused PDEs */
358 
359  /* Acquire PFN lock */
361  PMMPDE pointerPde;
365  {
367  {
368  pointerPde = MiAddressToPde(Address);
369  if (pointerPde->u.Hard.Valid)
370  MiDeletePte(pointerPde, MiPdeToPte(pointerPde), Process, NULL);
371  ASSERT(pointerPde->u.Hard.Valid == 0);
372  }
373  }
374  /* Release lock */
376  }
377 #endif
378  do
379  {
380  ULONG OldTarget = InitialTarget;
381 
382  /* Trim each consumer */
383  for (i = 0; i < MC_MAXIMUM; i++)
384  {
385  InitialTarget = MiTrimMemoryConsumer(i, InitialTarget);
386  }
387 
388  /* No pages left to swap! */
389  if (InitialTarget != 0 &&
390  InitialTarget == OldTarget)
391  {
392  /* Game over */
393  KeBugCheck(NO_PAGES_AVAILABLE);
394  }
395  }
396  while (InitialTarget != 0);
397  }
398  else
399  {
400  DPRINT1("KeWaitForMultipleObjects failed, status = %x\n", Status);
401  KeBugCheck(MEMORY_MANAGEMENT);
402  }
403  }
404 }
#define MiAddressToPde(x)
Definition: mmx86.c:20
#define MI_LOWEST_VAD_ADDRESS
Definition: miarm.h:11
LONG NTSTATUS
Definition: precomp.h:26
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
FORCEINLINE USHORT MiQueryPageTableReferences(IN PVOID Address)
Definition: miarm.h:1687
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
VOID NTAPI MiDeletePte(IN PMMPTE PointerPte, IN PVOID VirtualAddress, IN PEPROCESS CurrentProcess, IN PMMPTE PrototypePte)
Definition: virtual.c:391
uint32_t ULONG_PTR
Definition: typedefs.h:64
static KEVENT MiBalancerEvent
Definition: balance.c:45
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define STATUS_WAIT_1
Definition: ntstatus.h:71
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
#define STATUS_WAIT_0
Definition: ntstatus.h:223
#define MC_MAXIMUM
Definition: mm.h:96
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1431
#define PsGetCurrentProcess
Definition: psfuncs.h:17
smooth NULL
Definition: ftsmooth.c:416
static WCHAR Address[46]
Definition: ping.c:68
union _MMPTE::@2276 u
ULONG NTAPI MiTrimMemoryConsumer(ULONG Consumer, ULONG InitialTarget)
Definition: balance.c:118
ULONG64 Valid
Definition: mmtypes.h:150
#define PTE_PER_PAGE
Definition: mm.h:20
NTSTATUS NTAPI KeWaitForMultipleObjects(IN ULONG Count, IN PVOID Object[], IN WAIT_TYPE WaitType, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL, OUT PKWAIT_BLOCK WaitBlockArray OPTIONAL)
Definition: wait.c:586
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
static BOOLEAN MiIsBalancerThread(VOID)
Definition: balance.c:210
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Status
Definition: gdiplustypes.h:24
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define MiPdeToPte(_Pde)
Definition: mm.h:235
#define DPRINT1
Definition: precomp.h:8
#define MM_HIGHEST_VAD_ADDRESS
Definition: mm.h:46
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
static KTIMER MiBalancerTimer
Definition: balance.c:46

Referenced by MiInitBalancerThread().

◆ MiInitBalancerThread()

INIT_FUNCTION VOID NTAPI MiInitBalancerThread ( VOID  )

Definition at line 449 of file balance.c.

450 {
453 #if !defined(__GNUC__)
454 
455  LARGE_INTEGER dummyJunkNeeded;
456  dummyJunkNeeded.QuadPart = -20000000; /* 2 sec */
457  ;
458 #endif
459 
460 
464 #if defined(__GNUC__)
465  (LARGE_INTEGER)(LONGLONG)-20000000LL, /* 2 sec */
466 #else
467  dummyJunkNeeded,
468 #endif
469  2000, /* 2 sec */
470  NULL);
471 
474  NULL,
475  NULL,
478  NULL);
479  if (!NT_SUCCESS(Status))
480  {
481  KeBugCheck(MEMORY_MANAGEMENT);
482  }
483 
487  &Priority,
488  sizeof(Priority));
489 
490 }
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1339
#define LL
Definition: tui.h:84
FORCEINLINE _Post_maybenull_ _Must_inspect_result_ _In_ SIZE_T _In_ ULONG _In_ EX_POOL_PRIORITY Priority
Definition: exfuncs.h:700
VOID NTAPI MiBalancerThread(PVOID Unused)
Definition: balance.c:328
#define __GNUC__
Definition: _icc.h:38
LONG NTSTATUS
Definition: precomp.h:26
#define LOW_REALTIME_PRIORITY
BOOLEAN NTAPI KeSetTimerEx(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN LONG Period, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:294
LONG KPRIORITY
Definition: compat.h:463
static KEVENT MiBalancerEvent
Definition: balance.c:45
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1431
static CLIENT_ID MiBalancerThreadId
Definition: balance.c:43
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI NtSetInformationThread(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, IN PVOID ThreadInformation, IN ULONG ThreadInformationLength)
Definition: query.c:2014
int64_t LONGLONG
Definition: typedefs.h:67
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:24
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
NTSTATUS NTAPI PsCreateSystemThread(OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE ProcessHandle, IN PCLIENT_ID ClientId, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext)
Definition: thread.c:602
static HANDLE MiBalancerThreadHandle
Definition: balance.c:44
VOID NTAPI KeInitializeTimerEx(OUT PKTIMER Timer, IN TIMER_TYPE Type)
Definition: timerobj.c:244
LONGLONG QuadPart
Definition: typedefs.h:113
static KTIMER MiBalancerTimer
Definition: balance.c:46

Referenced by MmInitSystem().

◆ MiIsBalancerThread()

static BOOLEAN MiIsBalancerThread ( VOID  )
static

Definition at line 210 of file balance.c.

211 {
212  return (MiBalancerThreadHandle != NULL) &&
214 }
static CLIENT_ID MiBalancerThreadId
Definition: balance.c:43
smooth NULL
Definition: ftsmooth.c:416
PsGetCurrentThreadId
Definition: CrNtStubs.h:7
HANDLE UniqueThread
Definition: compat.h:484
static HANDLE MiBalancerThreadHandle
Definition: balance.c:44

Referenced by MiBalancerThread(), MmRebalanceMemoryConsumers(), and MmRequestPageMemoryConsumer().

◆ MiTrimMemoryConsumer()

ULONG NTAPI MiTrimMemoryConsumer ( ULONG  Consumer,
ULONG  InitialTarget 
)

Definition at line 118 of file balance.c.

119 {
120  ULONG Target = InitialTarget;
121  ULONG NrFreedPages = 0;
123 
124  /* Make sure we can trim this consumer */
125  if (!MiMemoryConsumers[Consumer].Trim)
126  {
127  /* Return the unmodified initial target */
128  return InitialTarget;
129  }
130 
131  if (MiMemoryConsumers[Consumer].PagesUsed > MiMemoryConsumers[Consumer].PagesTarget)
132  {
133  /* Consumer page limit exceeded */
134  Target = max(Target, MiMemoryConsumers[Consumer].PagesUsed - MiMemoryConsumers[Consumer].PagesTarget);
135  }
137  {
138  /* Global page limit exceeded */
140  }
141 
142  if (Target)
143  {
144  if (!InitialTarget)
145  {
146  /* If there was no initial target,
147  * swap at least MiMinimumPagesPerRun */
149  }
150 
151  /* Now swap the pages out */
152  Status = MiMemoryConsumers[Consumer].Trim(Target, 0, &NrFreedPages);
153 
154  DPRINT("Trimming consumer %lu: Freed %lu pages with a target of %lu pages\n", Consumer, NrFreedPages, Target);
155 
156  if (!NT_SUCCESS(Status))
157  {
158  KeBugCheck(MEMORY_MANAGEMENT);
159  }
160 
161  /* Update the target */
162  if (NrFreedPages < Target)
163  Target -= NrFreedPages;
164  else
165  Target = 0;
166 
167  /* Return the remaining pages needed to meet the target */
168  return Target;
169  }
170  else
171  {
172  /* Initial target is zero and we don't have anything else to add */
173  return 0;
174  }
175 }
#define max(a, b)
Definition: svc.c:63
static ULONG MiMinimumPagesPerRun
Definition: balance.c:41
LONG NTSTATUS
Definition: precomp.h:26
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1431
void DPRINT(...)
Definition: polytest.cpp:61
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS(* Trim)(ULONG Target, ULONG Priority, PULONG NrFreed)
Definition: mm.h:387
_Must_inspect_result_ typedef _In_ ULONG _In_ BOOLEAN Target
Definition: iotypes.h:1070
MM_MEMORY_CONSUMER MiMemoryConsumers[MC_MAXIMUM]
Definition: balance.c:36
Status
Definition: gdiplustypes.h:24
unsigned int ULONG
Definition: retypes.h:1
static ULONG MiMinimumAvailablePages
Definition: balance.c:37

Referenced by MiBalancerThread().

◆ MiZeroPhysicalPage()

VOID NTAPI MiZeroPhysicalPage ( IN PFN_NUMBER  PageFrameIndex)

Definition at line 122 of file pfnlist.c.

123 {
124  KIRQL OldIrql;
127 
128  /* Map in hyperspace, then wipe it using XMMI or MEMSET */
133 }
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define PsGetCurrentProcess
Definition: psfuncs.h:17
PVOID NTAPI MiMapPageInHyperSpace(IN PEPROCESS Process, IN PFN_NUMBER Page, IN PKIRQL OldIrql)
Definition: hypermap.c:30
VOID FASTCALL KeZeroPages(IN PVOID Address, IN ULONG Size)
Definition: stubs.c:82
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
VOID NTAPI MiUnmapPageInHyperSpace(IN PEPROCESS Process, IN PVOID Address, IN KIRQL OldIrql)
Definition: hypermap.c:93
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define PAGE_SIZE
Definition: env_spec_w32.h:49
_In_ ULONG _In_ BOOLEAN _Must_inspect_result_ PVOID * VirtualAddress
Definition: ndis.h:3791
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219

Referenced by MiRemoveZeroPage(), and MmRosNotifyAvailablePage().

◆ MmInitializeBalancer()

INIT_FUNCTION VOID NTAPI MmInitializeBalancer ( ULONG  NrAvailablePages,
ULONG  NrSystemPages 
)

Definition at line 53 of file balance.c.

54 {
58 
59  MiNrTotalPages = NrAvailablePages;
60 
61  /* Set up targets. */
64  if ((NrAvailablePages + NrSystemPages) >= 8192)
65  {
66  MiMemoryConsumers[MC_CACHE].PagesTarget = NrAvailablePages / 4 * 3;
67  }
68  else if ((NrAvailablePages + NrSystemPages) >= 4096)
69  {
70  MiMemoryConsumers[MC_CACHE].PagesTarget = NrAvailablePages / 3 * 2;
71  }
72  else
73  {
74  MiMemoryConsumers[MC_CACHE].PagesTarget = NrAvailablePages / 8;
75  }
77 }
static LIST_ENTRY AllocationListHead
Definition: balance.c:39
static ULONG MiMinimumPagesPerRun
Definition: balance.c:41
#define MC_USER
Definition: mm.h:94
ULONG PagesTarget
Definition: mm.h:386
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:238
static ULONG MiNrTotalPages
Definition: balance.c:38
static KSPIN_LOCK AllocationListLock
Definition: balance.c:40
MM_MEMORY_CONSUMER MiMemoryConsumers[MC_MAXIMUM]
Definition: balance.c:36
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define MC_CACHE
Definition: mm.h:93
static ULONG MiMinimumAvailablePages
Definition: balance.c:37
#define memset(x, y, z)
Definition: compat.h:39

Referenced by MiInitMachineDependent().

◆ MmInitializeMemoryConsumer()

INIT_FUNCTION VOID NTAPI MmInitializeMemoryConsumer ( ULONG  Consumer,
NTSTATUS(*)(ULONG Target, ULONG Priority, PULONG NrFreed)  Trim 
)

Definition at line 82 of file balance.c.

85 {
86  MiMemoryConsumers[Consumer].Trim = Trim;
87 }
NTSTATUS(* Trim)(ULONG Target, ULONG Priority, PULONG NrFreed)
Definition: mm.h:387
MM_MEMORY_CONSUMER MiMemoryConsumers[MC_MAXIMUM]
Definition: balance.c:36

Referenced by CcInitView(), and MmInitSystem().

◆ MmRebalanceMemoryConsumers()

VOID NTAPI MmRebalanceMemoryConsumers ( VOID  )

Definition at line 218 of file balance.c.

219 {
220  if (MiBalancerThreadHandle != NULL &&
222  {
224  }
225 }
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
static KEVENT MiBalancerEvent
Definition: balance.c:45
smooth NULL
Definition: ftsmooth.c:416
static BOOLEAN MiIsBalancerThread(VOID)
Definition: balance.c:210
#define IO_NO_INCREMENT
Definition: iotypes.h:568
static HANDLE MiBalancerThreadHandle
Definition: balance.c:44

Referenced by MiDecrementAvailablePages(), and MmRequestPageMemoryConsumer().

◆ MmReleasePageMemoryConsumer()

NTSTATUS NTAPI MmReleasePageMemoryConsumer ( ULONG  Consumer,
PFN_NUMBER  Page 
)

Definition at line 97 of file balance.c.

98 {
99  if (Page == 0)
100  {
101  DPRINT1("Tried to release page zero.\n");
102  KeBugCheck(MEMORY_MANAGEMENT);
103  }
104 
105  if (MmGetReferenceCountPage(Page) == 1)
106  {
107  if(Consumer == MC_USER) MmRemoveLRUUserPage(Page);
108  (void)InterlockedDecrementUL(&MiMemoryConsumers[Consumer].PagesUsed);
109  }
110 
111  MmDereferencePage(Page);
112 
113  return(STATUS_SUCCESS);
114 }
VOID NTAPI MmDereferencePage(PFN_NUMBER Page)
Definition: freelist.c:537
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
#define MC_USER
Definition: mm.h:94
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1431
ULONG NTAPI MmGetReferenceCountPage(PFN_NUMBER Page)
Definition: freelist.c:509
VOID NTAPI MmRemoveLRUUserPage(PFN_NUMBER Page)
Definition: freelist.c:116
MM_MEMORY_CONSUMER MiMemoryConsumers[MC_MAXIMUM]
Definition: balance.c:36
#define InterlockedDecrementUL(Addend)
Definition: ex.h:1510
#define DPRINT1
Definition: precomp.h:8
return STATUS_SUCCESS
Definition: btrfs.c:3014

Referenced by _MiFlushMappedSection(), CcFreeCachePage(), MiCowCacheSectionPage(), MiFreeSegmentPage(), MiGetOnePage(), MiReadFilePage(), MmCreateProcessAddressSpace(), MmDeleteVirtualMapping(), MmFinalizeSectionPageOut(), MmFreeCacheSectionPage(), MmFreePageTable(), MmFreeSectionPage(), MmGetPageTableForProcess(), MmGetPageTableForProcessForPAE(), MmNotPresentFaultCachePage(), MmPageOutCacheSection(), MmPageOutDeleteMapping(), MmPageOutSectionView(), MmpFreePageFileSegment(), and MmUnsharePageEntrySectionSegment().

◆ MmRequestPageMemoryConsumer()

NTSTATUS NTAPI MmRequestPageMemoryConsumer ( ULONG  Consumer,
BOOLEAN  CanWait,
PPFN_NUMBER  AllocatedPage 
)

Definition at line 229 of file balance.c.

231 {
232  ULONG PagesUsed;
233  PFN_NUMBER Page;
234 
235  /*
236  * Make sure we don't exceed our individual target.
237  */
238  PagesUsed = InterlockedIncrementUL(&MiMemoryConsumers[Consumer].PagesUsed);
239  if (PagesUsed > MiMemoryConsumers[Consumer].PagesTarget &&
241  {
243  }
244 
245  /*
246  * Allocate always memory for the non paged pool and for the pager thread.
247  */
248  if ((Consumer == MC_SYSTEM) /* || MiIsBalancerThread() */)
249  {
250  Page = MmAllocPage(Consumer);
251  if (Page == 0)
252  {
253  KeBugCheck(NO_PAGES_AVAILABLE);
254  }
255  if (Consumer == MC_USER) MmInsertLRULastUserPage(Page);
256  *AllocatedPage = Page;
259  return(STATUS_SUCCESS);
260  }
261 
262  /*
263  * Make sure we don't exceed global targets.
264  */
267  {
269 
270  if (!CanWait)
271  {
272  (void)InterlockedDecrementUL(&MiMemoryConsumers[Consumer].PagesUsed);
274  return(STATUS_NO_MEMORY);
275  }
276 
277  /* Insert an allocation request. */
278  Request.Page = 0;
280 
283 
285  0,
286  KernelMode,
287  FALSE,
288  NULL);
289 
290  Page = Request.Page;
291  if (Page == 0)
292  {
293  KeBugCheck(NO_PAGES_AVAILABLE);
294  }
295 
296  if(Consumer == MC_USER) MmInsertLRULastUserPage(Page);
297  *AllocatedPage = Page;
298 
300  {
302  }
303 
304  return(STATUS_SUCCESS);
305  }
306 
307  /*
308  * Actually allocate the page.
309  */
310  Page = MmAllocPage(Consumer);
311  if (Page == 0)
312  {
313  KeBugCheck(NO_PAGES_AVAILABLE);
314  }
315  if(Consumer == MC_USER) MmInsertLRULastUserPage(Page);
316  *AllocatedPage = Page;
317 
319  {
321  }
322 
323  return(STATUS_SUCCESS);
324 }
VOID NTAPI MmRebalanceMemoryConsumers(VOID)
Definition: balance.c:218
static LIST_ENTRY AllocationListHead
Definition: balance.c:39
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
#define MC_USER
Definition: mm.h:94
PLIST_ENTRY NTAPI ExInterlockedInsertTailList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:140
#define MC_SYSTEM
Definition: mm.h:95
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
_In_ NDIS_HANDLE _In_ PNDIS_REQUEST Request
Definition: ndis.h:5173
ULONG PFN_NUMBER
Definition: ke.h:8
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1431
smooth NULL
Definition: ftsmooth.c:416
PFN_NUMBER NTAPI MmAllocPage(ULONG Consumer)
Definition: freelist.c:569
static KSPIN_LOCK AllocationListLock
Definition: balance.c:40
MM_MEMORY_CONSUMER MiMemoryConsumers[MC_MAXIMUM]
Definition: balance.c:36
#define InterlockedDecrementUL(Addend)
Definition: ex.h:1510
static BOOLEAN MiIsBalancerThread(VOID)
Definition: balance.c:210
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define InterlockedIncrementUL(Addend)
Definition: ex.h:1513
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
unsigned int ULONG
Definition: retypes.h:1
static ULONG MiMinimumAvailablePages
Definition: balance.c:37
return STATUS_SUCCESS
Definition: btrfs.c:3014
VOID NTAPI MmInsertLRULastUserPage(PFN_NUMBER Page)
Definition: freelist.c:82

Referenced by CcInitCacheZeroPage(), CcRosMapVacbInKernelSpace(), MiGetOnePage(), MiGetPageTableForProcess(), MiReadFilePage(), MiReadPage(), MiSwapInPage(), MmAccessFaultSectionView(), MmCreateProcessAddressSpace(), MmGetPageTableForProcess(), MmGetPageTableForProcessForPAE(), and MmNotPresentFaultSectionView().

◆ MmRosNotifyAvailablePage()

BOOLEAN MmRosNotifyAvailablePage ( PFN_NUMBER  Page)

Definition at line 406 of file balance.c.

407 {
410  PMMPFN Pfn1;
411 
412  /* Make sure the PFN lock is held */
414 
416  {
417  /* Dirty way to know if we were initialized. */
418  return FALSE;
419  }
420 
422  if (!Entry)
423  return FALSE;
424 
426  MiZeroPhysicalPage(Page);
427  Request->Page = Page;
428 
429  Pfn1 = MiGetPfnEntry(Page);
430  ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
431  Pfn1->u3.e2.ReferenceCount = 1;
433 
434  /* This marks the PFN as a ReactOS PFN */
435  Pfn1->u4.AweAllocation = TRUE;
436 
437  /* Allocate the extra ReactOS Data and zero it out */
438  Pfn1->u1.SwapEntry = 0;
439  Pfn1->RmapListHead = NULL;
440 
442 
443  return TRUE;
444 }
static LIST_ENTRY AllocationListHead
Definition: balance.c:39
#define TRUE
Definition: types.h:120
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:936
struct _Entry Entry
Definition: kefuncs.h:627
ULONG_PTR AweAllocation
Definition: mm.h:353
PMM_RMAP_ENTRY RmapListHead
Definition: mm.h:343
union _MMPFN::@1772 u4
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
USHORT PageLocation
Definition: mm.h:297
_In_ NDIS_HANDLE _In_ PNDIS_REQUEST Request
Definition: ndis.h:5173
MMPFNENTRY e1
Definition: mm.h:329
PLIST_ENTRY NTAPI ExInterlockedRemoveHeadList(IN OUT PLIST_ENTRY ListHead, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:166
smooth NULL
Definition: ftsmooth.c:416
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
union _MMPFN::@1769 u3
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
static KSPIN_LOCK AllocationListLock
Definition: balance.c:40
Definition: mm.h:305
Definition: typedefs.h:118
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:940
union _MMPFN::@1767 u1
SWAPENTRY SwapEntry
Definition: mm.h:316
VOID NTAPI MiZeroPhysicalPage(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:122
struct _MMPFN::@1769::@1775 e2
#define IO_NO_INCREMENT
Definition: iotypes.h:568
static ULONG MiMinimumAvailablePages
Definition: balance.c:37
base of all file and directory entries
Definition: entries.h:82

Referenced by MiInsertPageInFreeList().

◆ MmTrimUserMemory()

NTSTATUS MmTrimUserMemory ( ULONG  Target,
ULONG  Priority,
PULONG  NrFreedPages 
)

Definition at line 178 of file balance.c.

179 {
180  PFN_NUMBER CurrentPage;
183 
184  (*NrFreedPages) = 0;
185 
186  CurrentPage = MmGetLRUFirstUserPage();
187  while (CurrentPage != 0 && Target > 0)
188  {
189  Status = MmPageOutPhysicalAddress(CurrentPage);
190  if (NT_SUCCESS(Status))
191  {
192  DPRINT("Succeeded\n");
193  Target--;
194  (*NrFreedPages)++;
195  }
196 
197  NextPage = MmGetLRUNextUserPage(CurrentPage);
198  if (NextPage <= CurrentPage)
199  {
200  /* We wrapped around, so we're done */
201  break;
202  }
203  CurrentPage = NextPage;
204  }
205 
206  return STATUS_SUCCESS;
207 }
LONG NTSTATUS
Definition: precomp.h:26
paddr_t NextPage
Definition: mmuobject.c:64
ULONG PFN_NUMBER
Definition: ke.h:8
void DPRINT(...)
Definition: polytest.cpp:61
NTSTATUS NTAPI MmPageOutPhysicalAddress(PFN_NUMBER Page)
Definition: rmap.c:57
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_Must_inspect_result_ typedef _In_ ULONG _In_ BOOLEAN Target
Definition: iotypes.h:1070
PFN_NUMBER NTAPI MmGetLRUFirstUserPage(VOID)
Definition: freelist.c:63
PFN_NUMBER NTAPI MmGetLRUNextUserPage(PFN_NUMBER PreviousPage)
Definition: freelist.c:97
Status
Definition: gdiplustypes.h:24
return STATUS_SUCCESS
Definition: btrfs.c:3014

Referenced by MmInitSystem().

Variable Documentation

◆ AllocationListHead

LIST_ENTRY AllocationListHead
static

◆ AllocationListLock

KSPIN_LOCK AllocationListLock
static

◆ MiBalancerEvent

KEVENT MiBalancerEvent
static

Definition at line 45 of file balance.c.

Referenced by MiBalancerThread(), MiInitBalancerThread(), and MmRebalanceMemoryConsumers().

◆ MiBalancerThreadHandle

HANDLE MiBalancerThreadHandle = NULL
static

Definition at line 44 of file balance.c.

Referenced by MiInitBalancerThread(), MiIsBalancerThread(), and MmRebalanceMemoryConsumers().

◆ MiBalancerThreadId

CLIENT_ID MiBalancerThreadId
static

Definition at line 43 of file balance.c.

Referenced by MiInitBalancerThread(), and MiIsBalancerThread().

◆ MiBalancerTimer

KTIMER MiBalancerTimer
static

Definition at line 46 of file balance.c.

Referenced by MiBalancerThread(), and MiInitBalancerThread().

◆ MiMemoryConsumers

◆ MiMinimumAvailablePages

ULONG MiMinimumAvailablePages
static

◆ MiMinimumPagesPerRun

ULONG MiMinimumPagesPerRun
static

Definition at line 41 of file balance.c.

Referenced by MiTrimMemoryConsumer(), and MmInitializeBalancer().

◆ MiNrTotalPages

ULONG MiNrTotalPages
static

Definition at line 38 of file balance.c.

Referenced by MmInitializeBalancer().