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, <tkreu...@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?rev=64589&r1=64588&r2=64589&view=diff
>
> ==============================================================================
> --- 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?rev=64589&r1=64588&r2=64589&view=diff
>
> ==============================================================================
> --- 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 for
> the VAD */
> -        EndingAddress = StartAddress + (ViewSizeInPages * PAGE_SIZE) - 1;
> -    }
> -    else
> -    {
> -        /* Get the ending address, which is the last piece we need for
> the 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 based
> section!\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 view
> was 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?rev=64589&r1=64588&r2=64589&view=diff
>
> ==============================================================================
> --- 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 for
> the 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?rev=64589&r1=64588&r2=64589&view=diff
>
> ==============================================================================
> --- 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 already
> dead
> -        //
> -        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 that
> is 64KB
> -        // aligned in the VAD tree. Otherwise, make sure that the address
> range
> -        // which was passed in isn't already conflicting with an existing
> address
> -        // 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 it
> doesn'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 VAD
> tree
> -        //
> -        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 the
> highest
> -        // virtual size we have ever seen, update the peak virtual size
> to reflect
> -        // this.
> -        //
> -        Process->VirtualSize += PRegionSize;
> -        if (Process->VirtualSize > Process->PeakVirtualSize)
> -        {
> -            Process->PeakVirtualSize = Process->VirtualSize;
> -        }
> -
> -        //
> -        // Release address space and detach and dereference the target
> process 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);
>
>
>
>
_______________________________________________
Ros-dev mailing list
Ros-dev@reactos.org
http://www.reactos.org/mailman/listinfo/ros-dev

Reply via email to