Author: ion Date: Fri Feb 17 22:57:32 2012 New Revision: 55676
URL: http://svn.reactos.org/svn/reactos?rev=55676&view=rev Log: [NTOSKRNL]: And finally, the third part of Richard's patch, cleaned up and ready to go. This cleans up the INIT and SCN_MEM_DISCARDABLE sections from all drivers and the kernel. Reduces RAM usage by another 350KB on my test box.
Modified: trunk/reactos/ntoskrnl/io/iomgr/driver.c trunk/reactos/ntoskrnl/mm/ARM3/sysldr.c trunk/reactos/ntoskrnl/mm/ARM3/zeropage.c
Modified: trunk/reactos/ntoskrnl/io/iomgr/driver.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/driver.c?... ============================================================================== --- trunk/reactos/ntoskrnl/io/iomgr/driver.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/io/iomgr/driver.c [iso-8859-1] Fri Feb 17 22:57:32 2012 @@ -422,6 +422,10 @@ return Status; }
+VOID +NTAPI +MmFreeDriverInitialization(IN PLDR_DATA_TABLE_ENTRY LdrEntry); + /* * IopInitializeDriverModule * @@ -513,6 +517,8 @@ DPRINT("IopCreateDriver() failed (Status 0x%08lx)\n", Status); return Status; } + + MmFreeDriverInitialization((PLDR_DATA_TABLE_ENTRY)Driver->DriverSection);
/* Set the driver as initialized */ IopReadyDeviceObjects(Driver);
Modified: trunk/reactos/ntoskrnl/mm/ARM3/sysldr.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/sysldr.c?r... ============================================================================== --- trunk/reactos/ntoskrnl/mm/ARM3/sysldr.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/ARM3/sysldr.c [iso-8859-1] Fri Feb 17 22:57:32 2012 @@ -1373,6 +1373,243 @@
VOID NTAPI +MiFreeInitializationCode(IN PVOID InitStart, + IN PVOID InitEnd) +{ + PMMPTE PointerPte; + PFN_NUMBER PagesFreed; + + /* Get the start PTE */ + PointerPte = MiAddressToPte(InitStart); + ASSERT(MI_IS_PHYSICAL_ADDRESS(InitStart) == FALSE); + + /* Compute the number of pages we expect to free */ + PagesFreed = (PFN_NUMBER)(MiAddressToPte(InitEnd) - PointerPte + 1); + + /* Try to actually free them */ + PagesFreed = MiDeleteSystemPageableVm(PointerPte, + PagesFreed, + 0, + NULL); +} + +VOID +NTAPI +INIT_FUNCTION +MiFindInitializationCode(OUT PVOID *StartVa, + OUT PVOID *EndVa) +{ + ULONG Size, SectionCount, Alignment; + PLDR_DATA_TABLE_ENTRY LdrEntry; + ULONG_PTR DllBase, InitStart, InitEnd, ImageEnd, InitCode; + PLIST_ENTRY NextEntry; + PIMAGE_NT_HEADERS NtHeader; + PIMAGE_SECTION_HEADER Section, LastSection; + BOOLEAN InitFound; + + /* So we don't free our own code yet */ + InitCode = (ULONG_PTR)&MiFindInitializationCode; + + /* Assume failure */ + *StartVa = NULL; + + /* Enter a critical region while we loop the list */ + KeEnterCriticalRegion(); + + /* Loop all loaded modules */ + NextEntry = PsLoadedModuleList.Flink; + while (NextEntry != &PsLoadedModuleList) + { + /* Get the loader entry and its DLL base */ + LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); + DllBase = (ULONG_PTR)LdrEntry->DllBase; + + /* Get the NT header */ + NtHeader = RtlImageNtHeader((PVOID)DllBase); + if (!NtHeader) + { + /* Keep going */ + NextEntry = NextEntry->Flink; + continue; + } + + /* Get the first section, the section count, and scan them all */ + Section = IMAGE_FIRST_SECTION(NtHeader); + SectionCount = NtHeader->FileHeader.NumberOfSections; + InitStart = 0; + while (SectionCount > 0) + { + /* Assume failure */ + InitFound = FALSE; + + /* Is this the INIT section or a discardable section? */ + if ((*(PULONG)Section->Name == 'TINI') || + ((Section->Characteristics & IMAGE_SCN_MEM_DISCARDABLE))) + { + /* Remember this */ + InitFound = TRUE; + } + + if (InitFound) + { + /* Pick the biggest size -- either raw or virtual */ + Size = max(Section->SizeOfRawData, Section->Misc.VirtualSize); + + /* Read the section alignment */ + Alignment = NtHeader->OptionalHeader.SectionAlignment; + + /* Align the start and end addresses appropriately */ + InitStart = DllBase + Section->VirtualAddress; + InitEnd = ((Alignment + InitStart + Size - 2) & 0xFFFFF000) - 1; + InitStart = (InitStart + (PAGE_SIZE - 1)) & 0xFFFFF000; + + /* Have we reached the last section? */ + if (SectionCount == 1) + { + /* Remember this */ + LastSection = Section; + } + else + { + /* We have not, loop all the sections */ + LastSection = NULL; + do + { + /* Keep going until we find a non-discardable section range */ + SectionCount--; + Section++; + if (Section->Characteristics & IMAGE_SCN_MEM_DISCARDABLE) + { + /* Discardable, so record it, then keep going */ + LastSection = Section; + } + else + { + /* Non-contigous discard flag, or no flag, break out */ + break; + } + } + while (SectionCount > 1); + } + + /* Have we found a discardable or init section? */ + if (LastSection) + { + /* Pick the biggest size -- either raw or virtual */ + Size = max(LastSection->SizeOfRawData, LastSection->Misc.VirtualSize); + + /* Use this as the end of the section address */ + InitEnd = DllBase + LastSection->VirtualAddress + Size - 1; + + /* Have we reached the last section yet? */ + if (SectionCount != 1) + { + /* Then align this accross the session boundary */ + InitEnd = ((Alignment + InitEnd - 1) & 0XFFFFF000) - 1; + } + } + + /* Make sure we don't let the init section go past the image */ + ImageEnd = DllBase + LdrEntry->SizeOfImage; + if (InitEnd > ImageEnd) InitEnd = (ImageEnd - 1) | (PAGE_SIZE - 1); + + /* Make sure we have a valid, non-zero init section */ + if (InitStart <= InitEnd) + { + /* Make sure we are not within this code itself */ + if ((InitCode >= InitStart) && (InitCode <= InitEnd)) + { + /* Return it, we can't free ourselves now */ + ASSERT(*StartVa == 0); + *StartVa = (PVOID)InitStart; + *EndVa = (PVOID)InitEnd; + } + else + { + /* This isn't us -- go ahead and free it */ + ASSERT(MI_IS_PHYSICAL_ADDRESS((PVOID)InitStart) == FALSE); + MiFreeInitializationCode((PVOID)InitStart, (PVOID)InitEnd); + } + } + } + + /* Move to the next section */ + SectionCount--; + Section++; + } + + /* Move to the next module */ + NextEntry = NextEntry->Flink; + } + + /* Leave the critical region and return */ + KeLeaveCriticalRegion(); +} + +/* + * Note: This function assumes that all discardable sections are at the end of + * the PE file. It searches backwards until it finds the non-discardable section + */ +VOID +NTAPI +MmFreeDriverInitialization(IN PLDR_DATA_TABLE_ENTRY LdrEntry) +{ + PMMPTE StartPte, EndPte; + PFN_NUMBER PageCount; + PVOID DllBase; + ULONG i; + PIMAGE_NT_HEADERS NtHeader; + PIMAGE_SECTION_HEADER Section, DiscardSection; + ULONG PagesDeleted; + + /* Get the base address and the page count */ + DllBase = LdrEntry->DllBase; + PageCount = LdrEntry->SizeOfImage >> PAGE_SHIFT; + + /* Get the last PTE in this image */ + EndPte = MiAddressToPte(DllBase) + PageCount; + + /* Get the NT header */ + NtHeader = RtlImageNtHeader(DllBase); + if (!NtHeader) return; + + /* Get the last section and loop each section backwards */ + Section = IMAGE_FIRST_SECTION(NtHeader) + NtHeader->FileHeader.NumberOfSections; + DiscardSection = NULL; + for (i = 0; i < NtHeader->FileHeader.NumberOfSections; i++) + { + /* Go back a section and check if it's discardable */ + Section--; + if (Section->Characteristics & IMAGE_SCN_MEM_DISCARDABLE) + { + /* It is, select it for freeing */ + DiscardSection = Section; + } + else + { + /* No more discardable sections exist, bail out */ + break; + } + } + + /* Bail out if there's nothing to free */ + if (!DiscardSection) return; + + /* Push the DLL base to the first disacrable section, and get its PTE */ + DllBase = (PVOID)ROUND_TO_PAGES((ULONG_PTR)DllBase + DiscardSection->VirtualAddress); + ASSERT(MI_IS_PHYSICAL_ADDRESS(DllBase) == FALSE); + StartPte = MiAddressToPte(DllBase); + + /* Check how many pages to free total */ + PageCount = (PFN_NUMBER)(EndPte - StartPte); + if (!PageCount) return; + + /* Delete this many PTEs */ + PagesDeleted = MiDeleteSystemPageableVm(StartPte, PageCount, 0, NULL); +} + +VOID +NTAPI INIT_FUNCTION MiReloadBootLoadedDrivers(IN PLOADER_PARAMETER_BLOCK LoaderBlock) {
Modified: trunk/reactos/ntoskrnl/mm/ARM3/zeropage.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/zeropage.c... ============================================================================== --- trunk/reactos/ntoskrnl/mm/ARM3/zeropage.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/ARM3/zeropage.c [iso-8859-1] Fri Feb 17 22:57:32 2012 @@ -24,19 +24,29 @@
VOID NTAPI +MiFindInitializationCode(OUT PVOID *StartVa, +OUT PVOID *EndVa); + +VOID +NTAPI +MiFreeInitializationCode(IN PVOID StartVa, +IN PVOID EndVa); + +VOID +NTAPI MmZeroPageThread(VOID) { PKTHREAD Thread = KeGetCurrentThread(); - //PVOID StartAddress, EndAddress; + PVOID StartAddress, EndAddress; PVOID WaitObjects[2]; KIRQL OldIrql; PVOID ZeroAddress; PFN_NUMBER PageIndex, FreePage; PMMPFN Pfn1;
- /* FIXME: Get the discardable sections to free them */ -// MiFindInitializationCode(&StartAddress, &EndAddress); -// if (StartAddress) MiFreeInitializationCode(StartAddress, EndAddress); + /* Get the discardable sections to free them */ + MiFindInitializationCode(&StartAddress, &EndAddress); + if (StartAddress) MiFreeInitializationCode(StartAddress, EndAddress); DPRINT1("Free non-cache pages: %lx\n", MmAvailablePages + MiMemoryConsumers[MC_CACHE].PagesUsed);
/* Set our priority to 0 */