Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

shutdown.c File Reference

#include "mi.h"

Go to the source code of this file.

Functions

VOID MmReleaseAllMemory (VOID)
BOOLEAN MmShutdownSystem (VOID)

Variables

ULONG MmSystemShutdown
ULONG MmZeroPageFile


Function Documentation

VOID MmReleaseAllMemory VOID   ) 
 

BOOLEAN MmShutdownSystem VOID   ) 
 

Definition at line 41 of file shutdown.c.

References ASSERT, _MMPAGING_FILE::Bitmap, _MDL::ByteCount, _SUBSECTION::ControlArea, ExPageLockHandle, FALSE, _MMPAGING_FILE::File, _CONTROL_AREA::FilePointer, _MMPFNLIST::Flink, IoSynchronousPageWrite(), KeClearEvent, KeDelayExecutionThread(), KeInitializeEvent, KernelMode, KeSetEvent(), KeWaitForSingleObject(), LOCK_PFN, _MDL::MappedSystemVa, MDL_MAPPED_TO_SYSTEM_VA, MDL_PAGES_LOCKED, _MDL::MdlFlags, MI_ADD_LOCKED_PAGE_CHARGE_FOR_MODIFIED_PAGE, MI_PFN_ELEMENT, MI_REMOVE_LOCKED_PAGE_CHARGE, MI_SET_PFN_DELETED, MiCheckControlArea(), MiDecrementReferenceCount(), MiGetSubsectionAddress, MiRemoveZeroPage(), MiStartingOffset(), MiUnlinkPageFromList(), MM_EMPTY_LIST, MM_MAXIMUM_WRITE_CLUSTER, MmAvailablePages, MmFreeGoal, MmInitializeMdl, MmLockPagableSectionByHandle(), MmModifiedPageListHead, MmModifiedPageWriterEvent, MmModifiedWriteClusterSize, MmNumberOfPagingFiles, MmPagingFile, MmSystemShutdown, MmTwentySeconds, MmUnlockPagableImageSection(), MmUnmapLockedPages(), MmZeroPageFile, NT_SUCCESS, NTSTATUS(), NULL, _CONTROL_AREA::NumberOfMappedViews, _CONTROL_AREA::NumberOfPfnReferences, _MMPFN::OriginalPte, PAGE_SHIFT, PAGE_SIZE, _MMPFN::PteAddress, _MMPAGING_FILE::Size, _MDL::StartVa, Status, TRUE, _CONTROL_AREA::u, _MMPTE::u, _MMPFN::u1, _MMPFN::u2, _MMPFN::u3, UNLOCK_PFN, and WrPageOut.

00047 : 00048 00049 This function performs the shutdown of memory management. This 00050 is accomplished by writing out all modified pages which are 00051 destined for files other than the paging file. 00052 00053 Arguments: 00054 00055 None. 00056 00057 Return Value: 00058 00059 TRUE if the pages were successfully written, FALSE otherwise. 00060 00061 --*/ 00062 00063 { 00064 PFN_NUMBER ModifiedPage; 00065 PMMPFN Pfn1; 00066 PSUBSECTION Subsection; 00067 PCONTROL_AREA ControlArea; 00068 PPFN_NUMBER Page; 00069 PFN_NUMBER MdlHack[(sizeof(MDL)/sizeof(PFN_NUMBER)) + MM_MAXIMUM_WRITE_CLUSTER]; 00070 PMDL Mdl; 00071 NTSTATUS Status; 00072 KEVENT IoEvent; 00073 IO_STATUS_BLOCK IoStatus; 00074 KIRQL OldIrql; 00075 LARGE_INTEGER StartingOffset; 00076 ULONG count; 00077 PFN_NUMBER j; 00078 ULONG k; 00079 PFN_NUMBER first; 00080 ULONG write; 00081 PMMPAGING_FILE PagingFile; 00082 00083 // 00084 // Don't do this more than once. 00085 // 00086 00087 if (!MmSystemShutdown) { 00088 00089 MmLockPagableSectionByHandle(ExPageLockHandle); 00090 00091 Mdl = (PMDL)&MdlHack; 00092 Page = (PPFN_NUMBER)(Mdl + 1); 00093 00094 KeInitializeEvent (&IoEvent, NotificationEvent, FALSE); 00095 00096 MmInitializeMdl(Mdl, 00097 NULL, 00098 PAGE_SIZE); 00099 00100 Mdl->MdlFlags |= MDL_PAGES_LOCKED; 00101 00102 LOCK_PFN (OldIrql); 00103 00104 ModifiedPage = MmModifiedPageListHead.Flink; 00105 while (ModifiedPage != MM_EMPTY_LIST) { 00106 00107 // 00108 // There are modified pages. 00109 // 00110 00111 Pfn1 = MI_PFN_ELEMENT (ModifiedPage); 00112 00113 if (Pfn1->OriginalPte.u.Soft.Prototype == 1) { 00114 00115 // 00116 // This page is destined for a file. 00117 // 00118 00119 Subsection = MiGetSubsectionAddress (&Pfn1->OriginalPte); 00120 ControlArea = Subsection->ControlArea; 00121 if ((!ControlArea->u.Flags.Image) && 00122 (!ControlArea->u.Flags.NoModifiedWriting)) { 00123 00124 MiUnlinkPageFromList (Pfn1); 00125 00126 // 00127 // Issue the write. 00128 // 00129 00130 Pfn1->u3.e1.Modified = 0; 00131 00132 // 00133 // Up the reference count for the physical page as there 00134 // is I/O in progress. 00135 // 00136 00137 MI_ADD_LOCKED_PAGE_CHARGE_FOR_MODIFIED_PAGE (Pfn1, 26); 00138 Pfn1->u3.e2.ReferenceCount += 1; 00139 00140 *Page = ModifiedPage; 00141 ControlArea->NumberOfMappedViews += 1; 00142 ControlArea->NumberOfPfnReferences += 1; 00143 00144 UNLOCK_PFN (OldIrql); 00145 00146 StartingOffset.QuadPart = MiStartingOffset (Subsection, 00147 Pfn1->PteAddress); 00148 00149 Mdl->StartVa = (PVOID)ULongToPtr(Pfn1->u3.e1.PageColor << PAGE_SHIFT); 00150 KeClearEvent (&IoEvent); 00151 Status = IoSynchronousPageWrite ( 00152 ControlArea->FilePointer, 00153 Mdl, 00154 &StartingOffset, 00155 &IoEvent, 00156 &IoStatus ); 00157 00158 // 00159 // Ignore all I/O failures - there is nothing that can be 00160 // done at this point. 00161 // 00162 00163 if (!NT_SUCCESS(Status)) { 00164 KeSetEvent (&IoEvent, 0, FALSE); 00165 } 00166 00167 Status = KeWaitForSingleObject (&IoEvent, 00168 WrPageOut, 00169 KernelMode, 00170 FALSE, 00171 (PLARGE_INTEGER)&MmTwentySeconds); 00172 00173 if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) { 00174 MmUnmapLockedPages (Mdl->MappedSystemVa, Mdl); 00175 } 00176 00177 if (Status == STATUS_TIMEOUT) { 00178 00179 // 00180 // The write did not complete in 20 seconds, assume 00181 // that the file systems are hung and return an 00182 // error. 00183 // 00184 00185 LOCK_PFN (OldIrql); 00186 Pfn1->u3.e1.Modified = 1; 00187 MI_REMOVE_LOCKED_PAGE_CHARGE (Pfn1, 27); 00188 MiDecrementReferenceCount (ModifiedPage); 00189 ControlArea->NumberOfMappedViews -= 1; 00190 ControlArea->NumberOfPfnReferences -= 1; 00191 00192 // 00193 // This routine returns with the PFN lock released! 00194 // 00195 00196 MiCheckControlArea (ControlArea, NULL, OldIrql); 00197 00198 MmUnlockPagableImageSection(ExPageLockHandle); 00199 00200 return FALSE; 00201 } 00202 00203 LOCK_PFN (OldIrql); 00204 MI_REMOVE_LOCKED_PAGE_CHARGE (Pfn1, 27); 00205 MiDecrementReferenceCount (ModifiedPage); 00206 ControlArea->NumberOfMappedViews -= 1; 00207 ControlArea->NumberOfPfnReferences -= 1; 00208 00209 // 00210 // This routine returns with the PFN lock released! 00211 // 00212 00213 MiCheckControlArea (ControlArea, NULL, OldIrql); 00214 LOCK_PFN (OldIrql); 00215 00216 // 00217 // Restart scan at the front of the list. 00218 // 00219 00220 ModifiedPage = MmModifiedPageListHead.Flink; 00221 continue; 00222 } 00223 } 00224 ModifiedPage = Pfn1->u1.Flink; 00225 } 00226 00227 UNLOCK_PFN (OldIrql); 00228 00229 // 00230 // If a high number of modified pages still exist, start the 00231 // modified page writer and wait for 5 seconds. 00232 // 00233 00234 if (MmAvailablePages < (MmFreeGoal * 2)) { 00235 LARGE_INTEGER FiveSeconds = {(ULONG)(-5 * 1000 * 1000 * 10), -1}; 00236 00237 KeSetEvent (&MmModifiedPageWriterEvent, 0, FALSE); 00238 KeDelayExecutionThread (KernelMode, 00239 FALSE, 00240 (PLARGE_INTEGER)&FiveSeconds); 00241 } 00242 00243 // 00244 // Indicate to the modified page writer that the system has 00245 // shutdown. 00246 // 00247 00248 MmSystemShutdown = 1; 00249 00250 // 00251 // Check to see if the paging file should be overwritten. 00252 // Only free blocks are written. 00253 // 00254 00255 if (MmZeroPageFile) { 00256 00257 // 00258 // Get pages to complete the write request. 00259 // 00260 00261 Mdl->StartVa = NULL; 00262 j = 0; 00263 k = 0; 00264 Page = (PPFN_NUMBER)(Mdl + 1); 00265 00266 LOCK_PFN (OldIrql); 00267 00268 if (MmAvailablePages < (MmModifiedWriteClusterSize + 20)) { 00269 UNLOCK_PFN(OldIrql); 00270 MmUnlockPagableImageSection(ExPageLockHandle); 00271 return TRUE; 00272 } 00273 00274 do { 00275 *Page = MiRemoveZeroPage ((ULONG)j); 00276 Pfn1 = MI_PFN_ELEMENT (*Page); 00277 Pfn1->u3.e2.ReferenceCount = 1; 00278 ASSERT (Pfn1->u2.ShareCount == 0); 00279 Pfn1->OriginalPte.u.Long = 0; 00280 MI_SET_PFN_DELETED (Pfn1); 00281 Page += 1; 00282 j += 1; 00283 } while (j < MmModifiedWriteClusterSize); 00284 00285 while (k < MmNumberOfPagingFiles) { 00286 00287 PagingFile = MmPagingFile[k]; 00288 00289 count = 0; 00290 write = FALSE; 00291 00292 for (j = 1; j < PagingFile->Size; j += 1) { 00293 00294 if (RtlCheckBit (PagingFile->Bitmap, j) == 0) { 00295 00296 if (count == 0) { 00297 first = j; 00298 } 00299 count += 1; 00300 if (count == MmModifiedWriteClusterSize) { 00301 write = TRUE; 00302 } 00303 } else { 00304 if (count != 0) { 00305 00306 // 00307 // Issue a write. 00308 // 00309 00310 write = TRUE; 00311 } 00312 } 00313 00314 if ((j == (PagingFile->Size - 1)) && 00315 (count != 0)) { 00316 write = TRUE; 00317 } 00318 00319 if (write) { 00320 00321 UNLOCK_PFN (OldIrql); 00322 00323 StartingOffset.QuadPart = (LONGLONG)first << PAGE_SHIFT; 00324 Mdl->ByteCount = count << PAGE_SHIFT; 00325 KeClearEvent (&IoEvent); 00326 00327 Status = IoSynchronousPageWrite (PagingFile->File, 00328 Mdl, 00329 &StartingOffset, 00330 &IoEvent, 00331 &IoStatus); 00332 00333 // 00334 // Ignore all I/O failures - there is nothing that can 00335 // be done at this point. 00336 // 00337 00338 if (!NT_SUCCESS(Status)) { 00339 KeSetEvent (&IoEvent, 0, FALSE); 00340 } 00341 00342 Status = KeWaitForSingleObject (&IoEvent, 00343 WrPageOut, 00344 KernelMode, 00345 FALSE, 00346 (PLARGE_INTEGER)&MmTwentySeconds); 00347 00348 if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) { 00349 MmUnmapLockedPages (Mdl->MappedSystemVa, Mdl); 00350 } 00351 00352 if (Status == STATUS_TIMEOUT) { 00353 00354 // 00355 // The write did not complete in 20 seconds, assume 00356 // that the file systems are hung and return an 00357 // error. 00358 // 00359 00360 j = 0; 00361 Page = (PPFN_NUMBER)(Mdl + 1); 00362 LOCK_PFN (OldIrql); 00363 do { 00364 MiDecrementReferenceCount (*Page); 00365 Page += 1; 00366 j += 1; 00367 } while (j < MmModifiedWriteClusterSize); 00368 UNLOCK_PFN (OldIrql); 00369 00370 MmUnlockPagableImageSection(ExPageLockHandle); 00371 return FALSE; 00372 } 00373 00374 count = 0; 00375 write = FALSE; 00376 LOCK_PFN (OldIrql); 00377 } 00378 } 00379 k += 1; 00380 } 00381 j = 0; 00382 Page = (PPFN_NUMBER)(Mdl + 1); 00383 do { 00384 MiDecrementReferenceCount (*Page); 00385 Page += 1; 00386 j += 1; 00387 } while (j < MmModifiedWriteClusterSize); 00388 UNLOCK_PFN (OldIrql); 00389 } 00390 MmUnlockPagableImageSection(ExPageLockHandle); 00391 } 00392 return TRUE; 00393 } }


Variable Documentation

ULONG MmSystemShutdown
 

Definition at line 25 of file shutdown.c.

Referenced by MiModifiedPageWriter(), MiModifiedPageWriterWorker(), and MmShutdownSystem().

ULONG MmZeroPageFile
 

Definition at line 37 of file shutdown.c.

Referenced by MmShutdownSystem().


Generated on Sat May 15 19:45:39 2004 for test by doxygen 1.3.7