I think it would be really great that instead of combining functions together for "removing code duplication" and not even bothering to think why there's a reason why the code was duplicated, people would work on actual improvements like Jerome or Pierre, instead of re-factoring code that works just to make it 'simpler'. Especially since this introduced a few bugs which had to be later fixed. There's a million bugs in ReactOS, including in the memory manager, so fixing those seems to make more sense than refactoring.
Just my 2 cents.
Best regards, Alex Ionescu
On Tue, Oct 7, 2014 at 5:31 PM, tkreuzer@svn.reactos.org wrote:
Author: tkreuzer Date: Wed Oct 8 00:31:17 2014 New Revision: 64589
URL: http://svn.reactos.org/svn/reactos?rev=64589&view=rev Log: [NTOSKRNL] Implement MiInsertVadEx, replacing duplicated code from NtAllocateVirtualMemory and MiMapViewOfDataSection
Modified: trunk/reactos/ntoskrnl/mm/ARM3/miarm.h trunk/reactos/ntoskrnl/mm/ARM3/section.c trunk/reactos/ntoskrnl/mm/ARM3/vadnode.c trunk/reactos/ntoskrnl/mm/ARM3/virtual.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/miarm.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/miarm.h?re...
============================================================================== --- trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] Wed Oct 8 00:31:17 2014 @@ -2144,6 +2144,16 @@ IN PEPROCESS Process );
+NTSTATUS +NTAPI +MiInsertVadEx(
- _Inout_ PMMVAD Vad,
- _In_ ULONG_PTR *BaseAddress,
- _In_ SIZE_T ViewSize,
- _In_ ULONG_PTR HighestAddress,
- _In_ ULONG_PTR Alignment,
- _In_ ULONG AllocationType);
VOID NTAPI MiInsertBasedSection(
Modified: trunk/reactos/ntoskrnl/mm/ARM3/section.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/section.c?...
============================================================================== --- trunk/reactos/ntoskrnl/mm/ARM3/section.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/ARM3/section.c [iso-8859-1] Wed Oct 8 00:31:17 2014 @@ -1252,9 +1252,7 @@ IN ULONG AllocationType) { PMMVAD_LONG Vad;
- PETHREAD Thread = PsGetCurrentThread();
- PMMSUPPORT AddressSpace;
- ULONG_PTR StartAddress, EndingAddress;
- ULONG_PTR StartAddress; ULONG_PTR ViewSizeInPages; PSUBSECTION Subsection; PSEGMENT Segment;
@@ -1263,8 +1261,6 @@ ULONG QuotaCharge = 0, QuotaExcess = 0; PMMPTE PointerPte, LastPte; MMPTE TempPte;
PMMADDRESS_NODE Parent;
TABLE_SEARCH_RESULT Result; DPRINT("Mapping ARM3 data section\n");
/* Get the segment for this section */
@@ -1361,6 +1357,7 @@
/* Write all the data required in the VAD for handling a fault */ Vad->ControlArea = ControlArea;
- Vad->u.VadFlags.CommitCharge = 0; Vad->u.VadFlags.Protection = ProtectionMask; Vad->u2.VadFlags2.FileOffset = (ULONG)(SectionOffset->QuadPart >> 16); Vad->u2.VadFlags2.Inherit = (InheritDisposition == ViewShare);
@@ -1437,100 +1434,23 @@ StartAddress = 0; }
- /* Lock the address space and make sure the process is alive */
- AddressSpace = MmGetCurrentAddressSpace();
- MmLockAddressSpace(AddressSpace);
- if (Process->VmDeleted)
- {
MmUnlockAddressSpace(AddressSpace);ExFreePoolWithTag(Vad, 'ldaV');DPRINT1("The process is dying\n");return STATUS_PROCESS_IS_TERMINATING;- }
- /* Did the caller specify an address? */
- if (StartAddress == 0)
- {
/* ARM3 does not support these flags yet */ASSERT(Process->VmTopDown == 0);ASSERT(ZeroBits == 0);/* Which way should we search? */if (AllocationType & MEM_TOP_DOWN){/* No, find an address top-down */Result = MiFindEmptyAddressRangeDownTree(*ViewSize,(ULONG_PTR)MM_HIGHEST_VAD_ADDRESS,
_64K,&Process->VadRoot,&StartAddress,&Parent);}else{/* No, find an address bottom-up */Result = MiFindEmptyAddressRangeInTree(*ViewSize,_64K,&Process->VadRoot,&Parent,&StartAddress);}/* Check if we found a suitable location */if (Result == TableFoundNode){DPRINT1("Not enough free space to insert this section!\n");MmUnlockAddressSpace(AddressSpace);MiDereferenceControlArea(ControlArea);ExFreePoolWithTag(Vad, 'ldaV');return STATUS_CONFLICTING_ADDRESSES;}/* Get the ending address, which is the last piece we need forthe VAD */
EndingAddress = StartAddress + (ViewSizeInPages * PAGE_SIZE) - 1;- }
- else
- {
/* Get the ending address, which is the last piece we need forthe VAD */
EndingAddress = StartAddress + (ViewSizeInPages * PAGE_SIZE) - 1;/* Make sure it doesn't conflict with an existing allocation */Result = MiCheckForConflictingNode(StartAddress >> PAGE_SHIFT,EndingAddress >> PAGE_SHIFT,&Process->VadRoot,&Parent);if (Result == TableFoundNode){DPRINT1("Conflict with SEC_BASED or manually basedsection!\n");
MmUnlockAddressSpace(AddressSpace);MiDereferenceControlArea(ControlArea);ExFreePoolWithTag(Vad, 'ldaV');return STATUS_CONFLICTING_ADDRESSES;}- }
- /* Now set the VAD address */
- Vad->StartingVpn = StartAddress >> PAGE_SHIFT;
- Vad->EndingVpn = EndingAddress >> PAGE_SHIFT;
- /* Pretend as if we own the working set */
- MiLockProcessWorkingSetUnsafe(Process, Thread);
- /* Insert the VAD */
- Process->VadRoot.NodeHint = Vad;
- MiInsertNode(&Process->VadRoot, (PVOID)Vad, Parent, Result);
- /* Release the working set */
- MiUnlockProcessWorkingSetUnsafe(Process, Thread);
- /* Unlock the address space */
- MmUnlockAddressSpace(AddressSpace);
Status = MiInsertVadEx((PMMVAD)Vad,
&StartAddress,ViewSizeInPages * PAGE_SIZE,MAXULONG_PTR >> ZeroBits,MM_VIRTMEM_GRANULARITY,AllocationType);if (!NT_SUCCESS(Status))
{
return Status;}
/* Windows stores this for accounting purposes, do so as well */ if (!Segment->u2.FirstMappedVa) Segment->u2.FirstMappedVa =
(PVOID)StartAddress;
/* Finally, let the caller know where, and for what size, the viewwas mapped */
- *ViewSize = (ULONG_PTR)EndingAddress - (ULONG_PTR)StartAddress + 1;
- *ViewSize = ViewSizeInPages * PAGE_SIZE; *BaseAddress = (PVOID)StartAddress; DPRINT("Start and region: 0x%p, 0x%p\n", *BaseAddress, *ViewSize); return STATUS_SUCCESS;
Modified: trunk/reactos/ntoskrnl/mm/ARM3/vadnode.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/vadnode.c?...
============================================================================== --- trunk/reactos/ntoskrnl/mm/ARM3/vadnode.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/ARM3/vadnode.c [iso-8859-1] Wed Oct 8 00:31:17 2014 @@ -193,6 +193,138 @@ MiInsertNode(&Process->VadRoot, (PVOID)Vad, Parent, Result); }
+NTSTATUS +NTAPI +MiInsertVadEx(
- _Inout_ PMMVAD Vad,
- _In_ ULONG_PTR *BaseAddress,
- _In_ SIZE_T ViewSize,
- _In_ ULONG_PTR HighestAddress,
- _In_ ULONG_PTR Alignment,
- _In_ ULONG AllocationType)
+{
- ULONG_PTR StartingAddress, EndingAddress;
- PEPROCESS CurrentProcess;
- PETHREAD CurrentThread;
- TABLE_SEARCH_RESULT Result;
- PMMADDRESS_NODE Parent;
- /* Align the view size to pages */
- ViewSize = ALIGN_UP_BY(ViewSize, PAGE_SIZE);
- /* Get the current process */
- CurrentProcess = PsGetCurrentProcess();
- /* Acquire the address creation lock and make sure the process is
alive */
- KeAcquireGuardedMutex(&CurrentProcess->AddressCreationLock);
- if (CurrentProcess->VmDeleted)
- {
KeReleaseGuardedMutex(&CurrentProcess->AddressCreationLock);DPRINT1("The process is dying\n");return STATUS_PROCESS_IS_TERMINATING;- }
- /* Did the caller specify an address? */
- if (*BaseAddress == 0)
- {
/* Make sure HighestAddress is not too large */HighestAddress = min(HighestAddress,(ULONG_PTR)MM_HIGHEST_VAD_ADDRESS);
/* Which way should we search? */if ((AllocationType & MEM_TOP_DOWN) || CurrentProcess->VmTopDown){/* Find an address top-down */Result = MiFindEmptyAddressRangeDownTree(ViewSize,HighestAddress,Alignment,&CurrentProcess->VadRoot,
&StartingAddress,&Parent);}else{/* Find an address bottom-up */Result = MiFindEmptyAddressRangeInTree(ViewSize,Alignment,&CurrentProcess->VadRoot,
&Parent,&StartingAddress);}/* Get the ending address, which is the last piece we need forthe VAD */
EndingAddress = StartingAddress + ViewSize - 1;/* Check if we found a suitable location */if ((Result == TableFoundNode) || (EndingAddress >HighestAddress))
{DPRINT1("Not enough free space to insert this VAD node!\n");KeReleaseGuardedMutex(&CurrentProcess->AddressCreationLock);return STATUS_CONFLICTING_ADDRESSES;}ASSERT(StartingAddress != 0);ASSERT(StartingAddress < (ULONG_PTR)HighestAddress);ASSERT(EndingAddress > StartingAddress);- }
- else
- {
/* Calculate the starting and ending address */StartingAddress = ALIGN_DOWN_BY(*BaseAddress, Alignment);EndingAddress = StartingAddress + ViewSize - 1;/* Make sure it doesn't conflict with an existing allocation */Result = MiCheckForConflictingNode(StartingAddress >> PAGE_SHIFT,EndingAddress >> PAGE_SHIFT,&CurrentProcess->VadRoot,&Parent);if (Result == TableFoundNode){DPRINT1("Given address conflicts with existing node\n");KeReleaseGuardedMutex(&CurrentProcess->AddressCreationLock);return STATUS_CONFLICTING_ADDRESSES;}- }
- /* Now set the VAD address */
- Vad->StartingVpn = StartingAddress >> PAGE_SHIFT;
- Vad->EndingVpn = EndingAddress >> PAGE_SHIFT;
- /* Check if the VAD is to be secured */
- if (Vad->u2.VadFlags2.OneSecured)
- {
/* This *must* be a long VAD! */ASSERT(Vad->u2.VadFlags2.LongVad);/* Yeah this is retarded, I didn't invent it! */((PMMVAD_LONG)Vad)->u3.Secured.StartVpn = StartingAddress;((PMMVAD_LONG)Vad)->u3.Secured.EndVpn = EndingAddress;- }
- /* Lock the working set */
- CurrentThread = PsGetCurrentThread();
- MiLockProcessWorkingSetUnsafe(CurrentProcess, CurrentThread);
- /* Insert the VAD */
- CurrentProcess->VadRoot.NodeHint = Vad;
- MiInsertNode(&CurrentProcess->VadRoot, (PVOID)Vad, Parent, Result);
- /* Release the working set */
- MiUnlockProcessWorkingSetUnsafe(CurrentProcess, CurrentThread);
- /* Update the process' virtual size, and peak virtual size */
- CurrentProcess->VirtualSize += ViewSize;
- if (CurrentProcess->VirtualSize > CurrentProcess->PeakVirtualSize)
- {
CurrentProcess->PeakVirtualSize = CurrentProcess->VirtualSize;- }
- /* Unlock the address space */
- KeReleaseGuardedMutex(&CurrentProcess->AddressCreationLock);
- *BaseAddress = StartingAddress;
- return STATUS_SUCCESS;
+}
VOID NTAPI MiInsertBasedSection(IN PSECTION Section)
Modified: trunk/reactos/ntoskrnl/mm/ARM3/virtual.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/virtual.c?...
============================================================================== --- trunk/reactos/ntoskrnl/mm/ARM3/virtual.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/ARM3/virtual.c [iso-8859-1] Wed Oct 8 00:31:17 2014 @@ -4304,12 +4304,12 @@ { PEPROCESS Process; PMEMORY_AREA MemoryArea;
- PFN_NUMBER PageCount; PMMVAD Vad = NULL, FoundVad; NTSTATUS Status; PMMSUPPORT AddressSpace; PVOID PBaseAddress;
- ULONG_PTR PRegionSize, StartingAddress, EndingAddress, HighestAddress;
- ULONG_PTR PRegionSize, StartingAddress, EndingAddress;
- ULONG_PTR HighestAddress = (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS; PEPROCESS CurrentProcess = PsGetCurrentProcess(); KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(); PETHREAD CurrentThread = PsGetCurrentThread();
@@ -4319,7 +4319,6 @@ MMPTE TempPte; PMMPTE PointerPte, PointerPde, LastPte; TABLE_SEARCH_RESULT Result;
PMMADDRESS_NODE Parent; PAGED_CODE();
/* Check for valid Zero bits */
@@ -4544,7 +4543,6 @@ // This is a blind commit, all we need is the region size // PRegionSize = ROUND_TO_PAGES(PRegionSize);
PageCount = BYTES_TO_PAGES(PRegionSize); EndingAddress = 0; StartingAddress = 0;@@ -4563,13 +4561,6 @@ goto FailPathNoLock; } }
else{//// Use the highest VAD address as maximum//HighestAddress = (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS;} } else {@@ -4579,8 +4570,8 @@ // fall based on the aligned address and the passed in region size // EndingAddress = ((ULONG_PTR)PBaseAddress + PRegionSize - 1) | (PAGE_SIZE - 1);
StartingAddress = ROUND_DOWN((ULONG_PTR)PBaseAddress, _64K);PageCount = BYTES_TO_PAGES(EndingAddress - StartingAddress);
PRegionSize = EndingAddress + 1 -ROUND_DOWN((ULONG_PTR)PBaseAddress, _64K);
StartingAddress = (ULONG_PTR)PBaseAddress; } //@@ -4594,7 +4585,7 @@ goto FailPathNoLock; }
Vad->u.LongFlags = 0;
RtlZeroMemory(Vad, sizeof(MMVAD_LONG)); if (AllocationType & MEM_COMMIT) Vad->u.VadFlags.MemCommit = 1; Vad->u.VadFlags.Protection = ProtectionMask; Vad->u.VadFlags.PrivateMemory = 1;@@ -4602,124 +4593,24 @@ Vad->ControlArea = NULL; // For Memory-Area hack
//
// Lock the address space and make sure the process isn't alreadydead
//AddressSpace = MmGetCurrentAddressSpace();MmLockAddressSpace(AddressSpace);if (Process->VmDeleted){Status = STATUS_PROCESS_IS_TERMINATING;goto FailPath;}//// Did we have a base address? If no, find a valid address thatis 64KB
// aligned in the VAD tree. Otherwise, make sure that the addressrange
// which was passed in isn't already conflicting with an existingaddress
// range.//if (!PBaseAddress){/* Which way should we search? */if ((AllocationType & MEM_TOP_DOWN) || Process->VmTopDown){/* Find an address top-down */Result = MiFindEmptyAddressRangeDownTree(PRegionSize,HighestAddress,_64K,&Process->VadRoot,
&StartingAddress,&Parent);}else{/* Find an address bottom-up */Result = MiFindEmptyAddressRangeInTree(PRegionSize,_64K,&Process->VadRoot,&Parent,&StartingAddress);}if (Result == TableFoundNode){Status = STATUS_NO_MEMORY;goto FailPath;}//// Now we know where the allocation ends. Make sure itdoesn't end up
// somewhere in kernel mode.//ASSERT(StartingAddress != 0);ASSERT(StartingAddress < (ULONG_PTR)MM_HIGHEST_USER_ADDRESS);EndingAddress = (StartingAddress + PRegionSize - 1) |(PAGE_SIZE - 1);
ASSERT(EndingAddress > StartingAddress);if (EndingAddress > HighestAddress){Status = STATUS_NO_MEMORY;goto FailPath;}}else{/* Make sure it doesn't conflict with an existing allocation*/
Result = MiCheckForConflictingNode(StartingAddress >>PAGE_SHIFT,
EndingAddress >>PAGE_SHIFT,
&Process->VadRoot,&Parent);if (Result == TableFoundNode){//// The address specified is in conflict!//Status = STATUS_CONFLICTING_ADDRESSES;goto FailPath;}}//// Write out the VAD fields for this allocation//Vad->StartingVpn = StartingAddress >> PAGE_SHIFT;Vad->EndingVpn = EndingAddress >> PAGE_SHIFT;//// FIXME: Should setup VAD bitmap//Status = STATUS_SUCCESS;//// Lock the working set and insert the VAD into the process VADtree
//MiLockProcessWorkingSetUnsafe(Process, CurrentThread);Process->VadRoot.NodeHint = Vad;MiInsertNode(&Process->VadRoot, (PVOID)Vad, Parent, Result);MiUnlockProcessWorkingSetUnsafe(Process, CurrentThread);//// Make sure the actual region size is at least as big as the// requested region size and update the value//ASSERT(PRegionSize <= (EndingAddress + 1 - StartingAddress));PRegionSize = (EndingAddress + 1 - StartingAddress);//// Update the virtual size of the process, and if this is now thehighest
// virtual size we have ever seen, update the peak virtual sizeto reflect
// this.//Process->VirtualSize += PRegionSize;if (Process->VirtualSize > Process->PeakVirtualSize){Process->PeakVirtualSize = Process->VirtualSize;}//// Release address space and detach and dereference the targetprocess if
// Insert the VAD//Status = MiInsertVadEx(Vad,&StartingAddress,PRegionSize,HighestAddress,MM_VIRTMEM_GRANULARITY,AllocationType);if (!NT_SUCCESS(Status)){DPRINT1("Failed to insert the VAD!\n");goto FailPathNoLock;}//// Detach and dereference the target process if // it was different from the current process //
MmUnlockAddressSpace(AddressSpace); if (Attached) KeUnstackDetachProcess(&ApcState); if (ProcessHandle != NtCurrentProcess())ObDereferenceObject(Process);