- Remove deprecated/old/buggy/unused code.

- Make MxGetNextPage return the lowest free physical page, not the highest.
  - This way we fragment the address space less.
  - Also makes calculation of "forgotten" pages when we build the PFN database earlier.
- Remove MmAllocEarlyPage and use MxGetNextPage instead.

svn path=/trunk/; revision=42175
This commit is contained in:
ReactOS Portable Systems Group
2009-07-24 15:49:27 +00:00
parent ce0ed78587
commit ab184fab15
4 changed files with 12 additions and 575 deletions
+1 -7
View File
@@ -1162,13 +1162,7 @@ KeBugCheckWithTf(IN ULONG BugCheckCode,
/* FIXME: Support Triage Dump */
/* Write the crash dump */
MmDumpToPagingFile(KiBugCheckData[4],
KiBugCheckData[0],
KiBugCheckData[1],
KiBugCheckData[2],
KiBugCheckData[3],
TrapFrame);
/* FIXME: Write the crash dump */
}
else
{
+3 -2
View File
@@ -250,9 +250,10 @@ MxGetNextPage(IN PFN_NUMBER PageCount)
}
//
// Use our highest usable free pages
// Use our lowest usable free pages
//
Pfn = MxFreeDescriptor->BasePage + MxFreeDescriptor->PageCount - PageCount;
Pfn = MxFreeDescriptor->BasePage;
MxFreeDescriptor->BasePage += PageCount;
MxFreeDescriptor->PageCount -= PageCount;
return Pfn;
}
+8 -277
View File
@@ -135,110 +135,6 @@ MmRemoveLRUUserPage(PFN_TYPE Page)
RemoveEntryList(&MiGetPfnEntry(Page)->ListEntry);
}
PFN_TYPE
NTAPI
MmGetContinuousPages(ULONG NumberOfBytes,
PHYSICAL_ADDRESS LowestAcceptableAddress,
PHYSICAL_ADDRESS HighestAcceptableAddress,
PHYSICAL_ADDRESS BoundaryAddressMultiple,
BOOLEAN ZeroPages)
{
ULONG NrPages;
ULONG i, j;
ULONG start;
ULONG last;
ULONG length;
ULONG boundary;
KIRQL oldIrql;
NrPages = PAGE_ROUND_UP(NumberOfBytes) / PAGE_SIZE;
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
last = min(HighestAcceptableAddress.LowPart / PAGE_SIZE, MmHighestPhysicalPage - 1);
boundary = BoundaryAddressMultiple.LowPart / PAGE_SIZE;
for (j = 0; j < 2; j++)
{
start = -1;
length = 0;
/* First try to allocate the pages above the 16MB area. This may fail
* because there are not enough continuous pages or we cannot allocate
* pages above the 16MB area because the caller has specify an upper limit.
* The second try uses the specified lower limit.
*/
for (i = j == 0 ? 0x100000 / PAGE_SIZE : LowestAcceptableAddress.LowPart / PAGE_SIZE; i <= last; )
{
if (MiGetPfnEntry(i)->Flags.Type == MM_PHYSICAL_PAGE_FREE)
{
if (start == (ULONG)-1)
{
start = i;
length = 1;
}
else
{
length++;
if (boundary)
{
if (start / boundary != i / boundary)
{
start = i;
length = 1;
}
}
}
if (length == NrPages)
{
break;
}
}
else
{
start = (ULONG)-1;
}
i++;
}
if (start != (ULONG)-1 && length == NrPages)
{
for (i = start; i < (start + length); i++)
{
PPHYSICAL_PAGE Page;
Page = MiGetPfnEntry(i);
RemoveEntryList(&Page->ListEntry);
if (MmPfnDatabase[i].Flags.Zero == 0)
{
UnzeroedPageCount--;
}
MmStats.NrFreePages--;
MmStats.NrSystemPages++;
Page->Flags.Type = MM_PHYSICAL_PAGE_USED;
Page->Flags.Consumer = MC_NPPOOL;
Page->ReferenceCount = 1;
Page->LockCount = 0;
Page->MapCount = 0;
Page->SavedSwapEntry = 0;
}
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
for (i = start; i < (start + length); i++)
{
if (MiGetPfnEntry(i)->Flags.Zero == 0)
{
if (ZeroPages) MiZeroPage(i);
}
else
{
MiGetPfnEntry(i)->Flags.Zero = 0;
}
}
return start;
}
}
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
return 0;
}
PFN_NUMBER
NTAPI
MiFindContiguousPages(IN PFN_NUMBER LowestPfn,
@@ -706,20 +602,6 @@ MiAllocatePagesForMdl(IN PHYSICAL_ADDRESS LowAddress,
return Mdl;
}
PFN_TYPE
NTAPI
MmAllocEarlyPage(VOID)
{
PFN_TYPE Pfn;
/* Use one of our highest usable pages */
Pfn = MxFreeDescriptor->BasePage + MxFreeDescriptor->PageCount - 1;
MxFreeDescriptor->PageCount--;
/* Return it */
return Pfn;
}
VOID
NTAPI
MmDumpPfnDatabase(VOID)
@@ -820,6 +702,10 @@ MmDumpPfnDatabase(VOID)
KeLowerIrql(OldIrql);
}
PFN_NUMBER
NTAPI
MxGetNextPage(IN PFN_NUMBER PageCount);
VOID
NTAPI
MmInitializePageList(VOID)
@@ -845,7 +731,7 @@ MmInitializePageList(VOID)
if (!MmIsPagePresent(NULL, Address))
{
/* Use one of our highest usable pages */
Pfn = MmAllocEarlyPage();
Pfn = MxGetNextPage(1);
/* Set the PFN */
Status = MmCreateVirtualMappingForKernel(Address,
@@ -934,9 +820,7 @@ MmInitializePageList(VOID)
}
/* Finally handle the pages describing the PFN database themselves */
for (i = (MxFreeDescriptor->BasePage + MxFreeDescriptor->PageCount);
i < (MxOldFreeDescriptor.BasePage + MxOldFreeDescriptor.PageCount);
i++)
for (i = MxOldFreeDescriptor.BasePage; i < MxFreeDescriptor->BasePage; i++)
{
/* Ensure this page was not added previously */
ASSERT(MmPfnDatabase[i].Flags.Type == 0);
@@ -945,9 +829,8 @@ MmInitializePageList(VOID)
MmPfnDatabase[i] = UsedPage;
MmStats.NrSystemPages++;
}
KeInitializeEvent(&ZeroPageThreadEvent, NotificationEvent, TRUE);
DPRINT("Pages: %x %x\n", MmStats.NrFreePages, MmStats.NrSystemPages);
MmStats.NrTotalPages = MmStats.NrFreePages + MmStats.NrSystemPages + MmStats.NrUserPages;
MmInitializeBalancer(MmStats.NrFreePages, MmStats.NrSystemPages);
@@ -1290,11 +1173,7 @@ MmAllocPage(ULONG Consumer, SWAPENTRY SwapEntry)
/* Check if this allocation is for the PFN DB itself */
if (MmStats.NrTotalPages == 0)
{
/* Allocate an early page -- we'll account for it later */
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
PfnOffset = MmAllocEarlyPage();
if (Consumer != MC_SYSTEM) MiZeroPage(PfnOffset);
return PfnOffset;
MxGetNextPage(1);
}
DPRINT1("MmAllocPage(): Out of memory\n");
@@ -1355,154 +1234,6 @@ MmAllocPage(ULONG Consumer, SWAPENTRY SwapEntry)
return PfnOffset;
}
LONG
NTAPI
MmAllocPagesSpecifyRange(ULONG Consumer,
PHYSICAL_ADDRESS LowestAddress,
PHYSICAL_ADDRESS HighestAddress,
ULONG NumberOfPages,
PPFN_TYPE Pages)
{
PPHYSICAL_PAGE PageDescriptor;
KIRQL oldIrql;
PFN_TYPE LowestPage, HighestPage;
PFN_TYPE pfn;
ULONG NumberOfPagesFound = 0;
ULONG i;
DPRINT("MmAllocPagesSpecifyRange()\n"
" LowestAddress = 0x%08x%08x\n"
" HighestAddress = 0x%08x%08x\n"
" NumberOfPages = %d\n",
LowestAddress.u.HighPart, LowestAddress.u.LowPart,
HighestAddress.u.HighPart, HighestAddress.u.LowPart,
NumberOfPages);
if (NumberOfPages == 0)
return 0;
LowestPage = LowestAddress.LowPart / PAGE_SIZE;
HighestPage = HighestAddress.LowPart / PAGE_SIZE;
if ((HighestAddress.u.LowPart % PAGE_SIZE) != 0)
HighestPage++;
if (LowestPage >= MmHighestPhysicalPage)
{
DPRINT1("MmAllocPagesSpecifyRange(): Out of memory\n");
return -1;
}
if (HighestPage > MmHighestPhysicalPage)
HighestPage = MmHighestPhysicalPage;
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
if (LowestPage == 0 && HighestPage == MmHighestPhysicalPage)
{
PLIST_ENTRY ListEntry;
while (NumberOfPagesFound < NumberOfPages)
{
if (!IsListEmpty(&FreeZeroedPageListHead))
{
ListEntry = RemoveTailList(&FreeZeroedPageListHead);
}
else if (!IsListEmpty(&FreeUnzeroedPageListHead))
{
ListEntry = RemoveTailList(&FreeUnzeroedPageListHead);
UnzeroedPageCount--;
}
else
{
if (NumberOfPagesFound == 0)
{
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
DPRINT1("MmAllocPagesSpecifyRange(): Out of memory\n");
return -1;
}
else
{
break;
}
}
PageDescriptor = CONTAINING_RECORD(ListEntry, PHYSICAL_PAGE, ListEntry);
ASSERT(PageDescriptor->Flags.Type == MM_PHYSICAL_PAGE_FREE);
ASSERT(PageDescriptor->MapCount == 0);
ASSERT(PageDescriptor->ReferenceCount == 0);
/* Allocate the page */
PageDescriptor->Flags.Type = MM_PHYSICAL_PAGE_USED;
PageDescriptor->Flags.Consumer = Consumer;
PageDescriptor->ReferenceCount = 1;
PageDescriptor->LockCount = 0;
PageDescriptor->MapCount = 0;
PageDescriptor->SavedSwapEntry = 0; /* FIXME: Do we need swap entries? */
MmStats.NrSystemPages++;
MmStats.NrFreePages--;
/* Remember the page */
pfn = PageDescriptor - MmPfnDatabase;
Pages[NumberOfPagesFound++] = pfn;
if(Consumer == MC_USER) MmInsertLRULastUserPage(pfn);
}
}
else
{
INT LookForZeroedPages;
for (LookForZeroedPages = 1; LookForZeroedPages >= 0; LookForZeroedPages--)
{
for (pfn = LowestPage; pfn < HighestPage; pfn++)
{
PageDescriptor = MmPfnDatabase + pfn;
if (PageDescriptor->Flags.Type != MM_PHYSICAL_PAGE_FREE)
continue;
if (PageDescriptor->Flags.Zero != LookForZeroedPages)
continue;
ASSERT(PageDescriptor->MapCount == 0);
ASSERT(PageDescriptor->ReferenceCount == 0);
/* Allocate the page */
PageDescriptor->Flags.Type = MM_PHYSICAL_PAGE_USED;
PageDescriptor->Flags.Consumer = Consumer;
PageDescriptor->ReferenceCount = 1;
PageDescriptor->LockCount = 0;
PageDescriptor->MapCount = 0;
PageDescriptor->SavedSwapEntry = 0; /* FIXME: Do we need swap entries? */
if (!PageDescriptor->Flags.Zero)
UnzeroedPageCount--;
MmStats.NrSystemPages++;
MmStats.NrFreePages--;
/* Remember the page */
Pages[NumberOfPagesFound++] = pfn;
if (NumberOfPagesFound == NumberOfPages)
break;
}
if (NumberOfPagesFound == NumberOfPages)
break;
}
}
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
/* Zero unzero-ed pages */
for (i = 0; i < NumberOfPagesFound; i++)
{
pfn = Pages[i];
if (MiGetPfnEntry(pfn)->Flags.Zero == 0)
{
MiZeroPage(pfn);
}
else
{
MiGetPfnEntry(pfn)->Flags.Zero = 0;
}
}
return NumberOfPagesFound;
}
NTSTATUS
NTAPI
MmZeroPageThreadMain(PVOID Ignored)
-289
View File
@@ -105,15 +105,6 @@ static ULONG MiReservedSwapPages;
*/
#define MM_PAGEFILE_COMMIT_GRACE (256)
static PVOID MmCoreDumpPageFrame = NULL;
static ULONG MmCoreDumpSize;
static DUMP_POINTERS MmCoreDumpPointers;
static PMM_CORE_DUMP_FUNCTIONS MmCoreDumpFunctions;
static ULONG MmCoreDumpPageFile = 0xFFFFFFFF;
static ROS_QUERY_LCN_MAPPING MmCoreDumpLcnMapping;
ULONG MmCoreDumpType = MM_CORE_DUMP_TYPE_NONE;
/*
* Translate between a swap entry and a file and offset pair.
*/
@@ -360,22 +351,6 @@ MmInitPagingFile(VOID)
PagingFileList[i] = NULL;
}
MiPagingFileCount = 0;
/*
* Initialize the crash dump support.
*/
if (MmCoreDumpType != MM_CORE_DUMP_TYPE_NONE)
{
MmCoreDumpPageFrame = MmAllocateSection(PAGE_SIZE, NULL);
if (MmCoreDumpType == MM_CORE_DUMP_TYPE_FULL)
{
MmCoreDumpSize = MmStats.NrTotalPages * 4096 + 1024 * 1024;
}
else
{
MmCoreDumpSize = 1024 * 1024;
}
}
}
BOOLEAN
@@ -538,263 +513,6 @@ MmAllocRetrievelDescriptorList(ULONG Pairs)
return RetDescList;
}
NTSTATUS NTAPI
MmDumpToPagingFile(ULONG BugCode,
ULONG BugCodeParameter1,
ULONG BugCodeParameter2,
ULONG BugCodeParameter3,
ULONG BugCodeParameter4,
PKTRAP_FRAME TrapFrame)
{
PMM_CORE_DUMP_HEADER Headers;
NTSTATUS Status;
UCHAR MdlBase[sizeof(MDL) + sizeof(ULONG)];
PMDL Mdl = (PMDL)MdlBase;
PETHREAD Thread = PsGetCurrentThread();
ULONG_PTR StackSize;
PULONG MdlMap;
LONGLONG NextOffset = 0;
ULONG i;
PRETRIEVAL_POINTERS_BUFFER RetrievalPointers;
LARGE_INTEGER DiskOffset;
if (MmCoreDumpPageFile == 0xFFFFFFFF)
{
return(STATUS_UNSUCCESSFUL);
}
DbgPrint("\nMM: Dumping core: ");
/* Prepare the dump headers. */
Headers = (PMM_CORE_DUMP_HEADER)MmCoreDumpPageFrame;
Headers->Magic = MM_CORE_DUMP_HEADER_MAGIC;
Headers->Version = MM_CORE_DUMP_HEADER_VERSION;
Headers->Type = MmCoreDumpType;
if (TrapFrame != NULL)
{
#ifdef _M_IX86
if (!(TrapFrame->EFlags & (1 << 17)))
{
memcpy(&Headers->TrapFrame, TrapFrame,
sizeof(KTRAP_FRAME) - (4 * sizeof(ULONG)));
}
else
#endif
{
memcpy(&Headers->TrapFrame, TrapFrame, sizeof(KTRAP_FRAME));
}
}
Headers->BugCheckCode = BugCode;
Headers->BugCheckParameters[0] = BugCodeParameter1;
Headers->BugCheckParameters[1] = BugCodeParameter2;
Headers->BugCheckParameters[2] = BugCodeParameter3;
Headers->BugCheckParameters[3] = BugCodeParameter4;
Headers->FaultingStackBase = (PVOID)Thread->Tcb.StackLimit;
Headers->FaultingStackSize =
StackSize = (ULONG_PTR)Thread->Tcb.StackBase - (ULONG_PTR)Thread->Tcb.StackLimit;
Headers->PhysicalMemorySize = MmStats.NrTotalPages * PAGE_SIZE;
/* Initialize the dump device. */
Status = MmCoreDumpFunctions->DumpInit();
if (!NT_SUCCESS(Status))
{
DPRINT1("MM: Failed to initialize core dump device.\n");
return(Status);
}
/* Initialize the MDL. */
MmInitializeMdl(Mdl, MmCoreDumpPageFrame, PAGE_SIZE);
Mdl->MdlFlags = MDL_PAGES_LOCKED|MDL_IO_PAGE_READ|MDL_SOURCE_IS_NONPAGED_POOL;
MdlMap = (PULONG)(Mdl + 1);
/* Initialize the retrieval offsets. */
RetrievalPointers = PagingFileList[MmCoreDumpPageFile]->RetrievalPointers;
/* Dump the header. */
MdlMap[0] = (ULONG)(MmGetPhysicalAddress(MmCoreDumpPageFrame).QuadPart >> PAGE_SHIFT);
#if defined(__GNUC__)
DiskOffset = MmGetOffsetPageFile(RetrievalPointers, (LARGE_INTEGER)0LL);
#else
{
const LARGE_INTEGER dummy =
{
0
};
DiskOffset = MmGetOffsetPageFile(RetrievalPointers, dummy);
}
#endif
DiskOffset.QuadPart += MmCoreDumpLcnMapping.LcnDiskOffset.QuadPart;
Status = MmCoreDumpFunctions->DumpWrite(DiskOffset, Mdl);
if (!NT_SUCCESS(Status))
{
DPRINT1("MM: Failed to write core dump header\n.");
return(Status);
}
NextOffset += PAGE_SIZE;
;
DbgPrint("00");
/* Write out the contents of physical memory. */
if (MmCoreDumpType == MM_CORE_DUMP_TYPE_FULL)
{
for (i = 0; i < MmStats.NrTotalPages; i++)
{
MdlMap[0] = i;
MmCreateVirtualMappingForKernel(MmCoreDumpPageFrame,
PAGE_READWRITE,
MdlMap,
1);
#if defined(__GNUC__)
DiskOffset = MmGetOffsetPageFile(RetrievalPointers,
(LARGE_INTEGER)NextOffset);
#else
{
LARGE_INTEGER dummy;
dummy.QuadPart = NextOffset;
DiskOffset = MmGetOffsetPageFile(RetrievalPointers, dummy);
}
#endif
DiskOffset.QuadPart += MmCoreDumpLcnMapping.LcnDiskOffset.QuadPart;
Status = MmCoreDumpFunctions->DumpWrite(DiskOffset, Mdl);
MmRawDeleteVirtualMapping(MmCoreDumpPageFrame);
if (!NT_SUCCESS(Status))
{
DPRINT1("MM: Failed to write page to core dump.\n");
return(Status);
}
if ((i % ((1024*1024) / PAGE_SIZE)) == 0)
{
DbgPrint("\b\b%.2d", i / ((1024*1024)/PAGE_SIZE));
}
NextOffset += PAGE_SIZE;
}
}
DbgPrint("\n");
MmCoreDumpFunctions->DumpFinish();
return(STATUS_SUCCESS);
}
NTSTATUS NTAPI
MmInitializeCrashDump(HANDLE PageFileHandle, ULONG PageFileNum)
{
PFILE_OBJECT PageFile;
PDEVICE_OBJECT PageFileDevice;
NTSTATUS Status;
PIRP Irp;
KEVENT Event;
IO_STATUS_BLOCK Iosb;
UNICODE_STRING DiskDumpName = RTL_CONSTANT_STRING(L"DiskDump");
ANSI_STRING ProcName;
PIO_STACK_LOCATION StackPtr;
PLDR_DATA_TABLE_ENTRY ModuleObject = NULL;
PVOID BaseAddress;
Status = ZwFsControlFile(PageFileHandle,
0,
NULL,
NULL,
&Iosb,
FSCTL_ROS_QUERY_LCN_MAPPING,
NULL,
0,
&MmCoreDumpLcnMapping,
sizeof(ROS_QUERY_LCN_MAPPING));
if (!NT_SUCCESS(Status) ||
Iosb.Information != sizeof(ROS_QUERY_LCN_MAPPING))
{
return(Status);
}
/* Get the underlying storage device. */
Status =
ObReferenceObjectByHandle(PageFileHandle,
FILE_ALL_ACCESS,
NULL,
KernelMode,
(PVOID*)&PageFile,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
PageFileDevice = PageFile->Vpb->RealDevice;
/* Get the dump pointers. */
KeInitializeEvent(&Event, NotificationEvent, FALSE);
Irp = IoBuildDeviceIoControlRequest(IOCTL_SCSI_GET_DUMP_POINTERS,
PageFileDevice,
NULL,
0,
&MmCoreDumpPointers,
sizeof(MmCoreDumpPointers),
FALSE,
&Event,
&Iosb);
if(Irp == NULL)
{
ObDereferenceObject(PageFile);
return(STATUS_NO_MEMORY);// tMk - is this correct return code ???
}
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->FileObject = PageFile;
StackPtr->DeviceObject = PageFileDevice;
StackPtr->Parameters.DeviceIoControl.InputBufferLength = 0;
StackPtr->Parameters.DeviceIoControl.OutputBufferLength = sizeof(MmCoreDumpPointers);
Status = IoCallDriver(PageFileDevice,Irp);
if (Status == STATUS_PENDING)
{
Status = KeWaitForSingleObject(&Event,
Executive,
KernelMode,
FALSE,
NULL);
}
if (Status != STATUS_SUCCESS ||
Iosb.Information != sizeof(MmCoreDumpPointers))
{
ObDereferenceObject(PageFile);
return(Status);
}
/* Load the diskdump driver. */
Status = MmLoadSystemImage(&DiskDumpName, NULL, NULL, 0, (PVOID)&ModuleObject, &BaseAddress);
if (ModuleObject == NULL)
{
return(STATUS_OBJECT_NAME_NOT_FOUND);
}
RtlInitAnsiString(&ProcName, "DiskDumpFunctions");
MmCoreDumpFunctions = MiFindExportedRoutineByName(BaseAddress,
&ProcName);
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(PageFile);
return(Status);
}
/* Prepare for disk dumping. */
Status = MmCoreDumpFunctions->DumpPrepare(PageFileDevice,
&MmCoreDumpPointers);
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(PageFile);
return(Status);
}
MmCoreDumpPageFile = PageFileNum;
ObDereferenceObject(PageFile);
return(STATUS_SUCCESS);
}
NTSTATUS NTAPI
NtCreatePagingFile(IN PUNICODE_STRING FileName,
IN PLARGE_INTEGER InitialSize,
@@ -1135,13 +853,6 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
MiPagingFileCount++;
KeReleaseSpinLock(&PagingFileListLock, oldIrql);
/* Check whether this pagefile can be a crash dump target. */
if (MmCoreDumpType != MM_CORE_DUMP_TYPE_NONE &&
PagingFile->CurrentSize.QuadPart >= MmCoreDumpSize &&
MmCoreDumpPageFile == 0xFFFFFFFF)
{
MmInitializeCrashDump(FileHandle, i);
}
ZwClose(FileHandle);
MmSwapSpaceMessage = FALSE;