[ros-diffs] [ros-arm-bringup] 41708: - Rewrite MmAllocateNonCachedMemory and MmFreeNonCachedMemory to use the new functionality present in ARM3. - These functions now use the MDL routines to allocate their physical memory, since the constraints and requirements are identical as for a non-cached MDL mapping. - As for the virtual address space, it is guaranteed once again by System PTEs! - If it's not getting old already, optimizations to the System PTE code will, yet again, yield improvements here as well. - This is the last large kernel-facing memory allocator that needed updating to use System PTEs instead. - Only the pool allocator remains (which, for nonpaged pool, also uses System PTEs, present in the nonpaged pool expansion VA). - That effort will take significantly longer.

ros-arm-bringup at svn.reactos.org ros-arm-bringup at svn.reactos.org
Tue Jun 30 10:55:20 CEST 2009


Author: ros-arm-bringup
Date: Tue Jun 30 12:55:18 2009
New Revision: 41708

URL: http://svn.reactos.org/svn/reactos?rev=41708&view=rev
Log:
- Rewrite MmAllocateNonCachedMemory and MmFreeNonCachedMemory to use the new functionality present in ARM3.
  - These functions now use the MDL routines to allocate their physical memory, since the constraints and requirements are identical as for a non-cached MDL mapping.
  - As for the virtual address space, it is guaranteed once again by System PTEs!
    - If it's not getting old already, optimizations to the System PTE code will, yet again, yield improvements here as well.
- This is the last large kernel-facing memory allocator that needed updating to use System PTEs instead.
  - Only the pool allocator remains (which, for nonpaged pool, also uses System PTEs, present in the nonpaged pool expansion VA).
    - That effort will take significantly longer.


Added:
    trunk/reactos/ntoskrnl/mm/ARM3/ncache.c
      - copied, changed from r41647, trunk/reactos/ntoskrnl/mm/ncache.c
Removed:
    trunk/reactos/ntoskrnl/mm/ncache.c
Modified:
    trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild

Copied: trunk/reactos/ntoskrnl/mm/ARM3/ncache.c (from r41647, trunk/reactos/ntoskrnl/mm/ncache.c)
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/ncache.c?p2=trunk/reactos/ntoskrnl/mm/ARM3/ncache.c&p1=trunk/reactos/ntoskrnl/mm/ncache.c&r1=41647&r2=41708&rev=41708&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ncache.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/ncache.c [iso-8859-1] Tue Jun 30 12:55:18 2009
@@ -1,128 +1,214 @@
 /*
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/mm/ncache.c
- * PURPOSE:         Manages non-cached memory
- *
- * PROGRAMMERS:     David Welch (welch at cwcom.net)
+ * PROJECT:         ReactOS Kernel
+ * LICENSE:         BSD - See COPYING.ARM in the top level directory
+ * FILE:            ntoskrnl/mm/ARM3/ncache.c
+ * PURPOSE:         ARM Memory Manager Noncached Memory Allocator
+ * PROGRAMMERS:     ReactOS Portable Systems Group
  */
 
-/* INCLUDES *****************************************************************/
+/* INCLUDES *******************************************************************/
 
 #include <ntoskrnl.h>
 #define NDEBUG
 #include <debug.h>
 
-/* FUNCTIONS *****************************************************************/
-
-
-/**********************************************************************
- * NAME       EXPORTED
- *  MmAllocateNonCachedMemory at 4
- *
- * DESCRIPTION
- *  Allocates a virtual address range of noncached and cache
- * aligned memory.
- *
- * ARGUMENTS
- * NumberOfBytes
- *  Size of region to allocate.
- *
- * RETURN VALUE
- * The base address of the range on success;
- * NULL on failure.
- *
- * NOTE
- *  Description taken from include/ddk/mmfuncs.h.
- *  Code taken from ntoskrnl/mm/special.c.
- *
- * REVISIONS
- *
+#line 15 "ARM³::NCACHE"
+#define MODULE_INVOLVED_IN_ARM3
+#include "../ARM3/miarm.h"
+
+/* GLOBALS ********************************************************************/
+
+/*
  * @implemented
  */
-PVOID NTAPI
+PVOID
+NTAPI
 MmAllocateNonCachedMemory(IN ULONG NumberOfBytes)
 {
-   PVOID Result;
-   MEMORY_AREA* marea;
-   NTSTATUS Status;
-   ULONG Protect = PAGE_READWRITE|PAGE_SYSTEM|PAGE_NOCACHE|PAGE_WRITETHROUGH;
-   PHYSICAL_ADDRESS BoundaryAddressMultiple;
-
-   BoundaryAddressMultiple.QuadPart = 0;
-   MmLockAddressSpace(MmGetKernelAddressSpace());
-   Result = NULL;
-   Status = MmCreateMemoryArea (MmGetKernelAddressSpace(),
-                                MEMORY_AREA_NO_CACHE,
-                                &Result,
+    PFN_NUMBER PageCount, MdlPageCount, PageFrameIndex;
+    PHYSICAL_ADDRESS LowAddress, HighAddress, SkipBytes;
+    MI_PFN_CACHE_ATTRIBUTE CacheAttribute;
+    PMDL Mdl;
+    PVOID BaseAddress;    
+    PPFN_NUMBER MdlPages;
+    PMMPTE PointerPte;
+    MMPTE TempPte;
+    
+    //
+    // Get the page count
+    //
+    ASSERT(NumberOfBytes != 0);
+    PageCount = BYTES_TO_PAGES(NumberOfBytes);
+    
+    //
+    // Use the MDL allocator for simplicity, so setup the parameters
+    //
+    LowAddress.QuadPart = 0;
+    HighAddress.QuadPart = -1;
+    SkipBytes.QuadPart = 0;    
+    CacheAttribute = MiPlatformCacheAttributes[0][MmNonCached];
+    
+    //
+    // Now call the MDL allocator
+    //
+    Mdl = MiAllocatePagesForMdl(LowAddress,
+                                HighAddress,
+                                SkipBytes,
                                 NumberOfBytes,
-                                Protect,
-                                &marea,
-                                FALSE,
-                                0,
-                                BoundaryAddressMultiple);
-   MmUnlockAddressSpace(MmGetKernelAddressSpace());
-
-   if (!NT_SUCCESS(Status))
-   {
-      DPRINT1("Allocating marea for noncached mem failed with Status "
-          "0x%08X\n", Status);
-      return (NULL);
-   }
-
-   /* Create a virtual mapping for this memory area */
-   MmMapMemoryArea(Result, NumberOfBytes, MC_NPPOOL, Protect);
-
-   return ((PVOID)Result);
+                                CacheAttribute,
+                                0);
+    if (!Mdl) return NULL;
+    
+    //
+    // Get the MDL VA and check how many pages we got (could be partial)
+    //
+    BaseAddress = (PVOID)((ULONG_PTR)Mdl->StartVa + Mdl->ByteOffset);
+    MdlPageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(BaseAddress, Mdl->ByteCount);
+    if (PageCount != MdlPageCount)
+    {
+        //
+        // Unlike MDLs, partial isn't okay for a noncached allocation, so fail
+        //
+        ASSERT(PageCount > MdlPageCount);
+        MmFreePagesFromMdl(Mdl);
+        ExFreePool(Mdl);
+        return NULL;
+    }
+    
+    //
+    // Allocate system PTEs for the base address
+    // We use an extra page to store the actual MDL pointer for the free later
+    //
+    PointerPte = MiReserveSystemPtes(PageCount + 1, SystemPteSpace);    
+    if (!PointerPte)
+    {
+        //
+        // Out of memory...
+        //
+        MmFreePagesFromMdl(Mdl);
+        ExFreePool(Mdl);
+        return NULL;
+    }
+    
+    //
+    // Store the MDL pointer
+    //
+    *(PMDL*)PointerPte++ = Mdl;
+    
+    //
+    // Okay, now see what range we got
+    //
+    BaseAddress = MiPteToAddress(PointerPte);
+    
+    //
+    // This is our array of pages
+    //
+    MdlPages = (PPFN_NUMBER)(Mdl + 1);
+    
+    //
+    // Setup the template PTE
+    //
+    TempPte = HyperTemplatePte;
+    
+    //
+    // Now check what kind of caching we should use
+    //
+    switch (CacheAttribute)
+    {
+        case MiNonCached:
+            
+            //
+            // Disable caching
+            //
+            TempPte.u.Hard.CacheDisable = 1;
+            TempPte.u.Hard.WriteThrough = 1;
+            break;
+            
+        case MiWriteCombined:
+            
+            //
+            // Enable write combining
+            //
+            TempPte.u.Hard.CacheDisable = 1;
+            TempPte.u.Hard.WriteThrough = 0;
+            break;
+            
+        default:
+            //
+            // Nothing to do
+            //
+            break;
+    }
+    
+    //
+    // Now loop the MDL pages
+    //
+    do
+    {
+        //
+        // Get the PFN
+        //
+        PageFrameIndex = *MdlPages++;
+        
+        //
+        // Set the PFN in the page and write it
+        //
+        TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
+        ASSERT(PointerPte->u.Hard.Valid == 0);
+        ASSERT(TempPte.u.Hard.Valid == 1);
+        *PointerPte++ = TempPte;
+    } while (--PageCount);
+    
+    //
+    // Return the base address
+    //
+    return BaseAddress;
+    
 }
 
-static VOID
-MmFreeNonCachedPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
-                    PFN_TYPE Page, SWAPENTRY SwapEntry,
-                    BOOLEAN Dirty)
-{
-   ASSERT(SwapEntry == 0);
-   if (Page != 0)
-   {
-      MmReleasePageMemoryConsumer(MC_NPPOOL, Page);
-   }
-}
-
-/**********************************************************************
- * NAME       EXPORTED
- * MmFreeNonCachedMemory at 8
- *
- * DESCRIPTION
- * Releases a range of noncached memory allocated with
- * MmAllocateNonCachedMemory.
- *
- * ARGUMENTS
- * BaseAddress
- *  Virtual address to be freed;
- *
- * NumberOfBytes
- *  Size of the region to be freed.
- *
- * RETURN VALUE
- *  None.
- *
- * NOTE
- *  Description taken from include/ddk/mmfuncs.h.
- *  Code taken from ntoskrnl/mm/special.c.
- *
- * REVISIONS
- *
+/*
  * @implemented
  */
-VOID NTAPI MmFreeNonCachedMemory (IN PVOID BaseAddress,
-                                    IN ULONG NumberOfBytes)
+VOID
+NTAPI
+MmFreeNonCachedMemory(IN PVOID BaseAddress,
+                      IN ULONG NumberOfBytes)
 {
-   MmLockAddressSpace(MmGetKernelAddressSpace());
-   MmFreeMemoryAreaByPtr(MmGetKernelAddressSpace(),
-                         BaseAddress,
-                         MmFreeNonCachedPage,
-                         NULL);
-   MmUnlockAddressSpace(MmGetKernelAddressSpace());
+    PMDL Mdl;
+    PMMPTE PointerPte;
+    PFN_NUMBER PageCount;
+    
+    //
+    // Sanity checks
+    //
+    ASSERT(NumberOfBytes != 0);
+    ASSERT(PAGE_ALIGN(BaseAddress) == BaseAddress);
+    
+    //
+    // Get the page count
+    //
+    PageCount = BYTES_TO_PAGES(NumberOfBytes);
+    
+    //
+    // Get the first PTE
+    //
+    PointerPte = MiAddressToPte(BaseAddress);
+    
+    //
+    // Remember this is where we store the shadow MDL pointer
+    //
+    Mdl = *(PMDL*)(--PointerPte);
+    
+    //
+    // Kill the MDL (and underlying pages)
+    //
+    MmFreePagesFromMdl(Mdl);
+    ExFreePool(Mdl);
+    
+    //
+    // Now free the system PTEs for the underlying VA
+    //
+    MiReleaseSystemPtes(PointerPte, PageCount + 1, SystemPteSpace);
 }
 
 /* EOF */

Removed: trunk/reactos/ntoskrnl/mm/ncache.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ncache.c?rev=41707&view=auto
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ncache.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ncache.c (removed)
@@ -1,128 +1,0 @@
-/*
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/mm/ncache.c
- * PURPOSE:         Manages non-cached memory
- *
- * PROGRAMMERS:     David Welch (welch at cwcom.net)
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <debug.h>
-
-/* FUNCTIONS *****************************************************************/
-
-
-/**********************************************************************
- * NAME       EXPORTED
- *  MmAllocateNonCachedMemory at 4
- *
- * DESCRIPTION
- *  Allocates a virtual address range of noncached and cache
- * aligned memory.
- *
- * ARGUMENTS
- * NumberOfBytes
- *  Size of region to allocate.
- *
- * RETURN VALUE
- * The base address of the range on success;
- * NULL on failure.
- *
- * NOTE
- *  Description taken from include/ddk/mmfuncs.h.
- *  Code taken from ntoskrnl/mm/special.c.
- *
- * REVISIONS
- *
- * @implemented
- */
-PVOID NTAPI
-MmAllocateNonCachedMemory(IN ULONG NumberOfBytes)
-{
-   PVOID Result;
-   MEMORY_AREA* marea;
-   NTSTATUS Status;
-   ULONG Protect = PAGE_READWRITE|PAGE_SYSTEM|PAGE_NOCACHE|PAGE_WRITETHROUGH;
-   PHYSICAL_ADDRESS BoundaryAddressMultiple;
-
-   BoundaryAddressMultiple.QuadPart = 0;
-   MmLockAddressSpace(MmGetKernelAddressSpace());
-   Result = NULL;
-   Status = MmCreateMemoryArea (MmGetKernelAddressSpace(),
-                                MEMORY_AREA_NO_CACHE,
-                                &Result,
-                                NumberOfBytes,
-                                Protect,
-                                &marea,
-                                FALSE,
-                                0,
-                                BoundaryAddressMultiple);
-   MmUnlockAddressSpace(MmGetKernelAddressSpace());
-
-   if (!NT_SUCCESS(Status))
-   {
-      DPRINT1("Allocating marea for noncached mem failed with Status "
-          "0x%08X\n", Status);
-      return (NULL);
-   }
-
-   /* Create a virtual mapping for this memory area */
-   MmMapMemoryArea(Result, NumberOfBytes, MC_NPPOOL, Protect);
-
-   return ((PVOID)Result);
-}
-
-static VOID
-MmFreeNonCachedPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
-                    PFN_TYPE Page, SWAPENTRY SwapEntry,
-                    BOOLEAN Dirty)
-{
-   ASSERT(SwapEntry == 0);
-   if (Page != 0)
-   {
-      MmReleasePageMemoryConsumer(MC_NPPOOL, Page);
-   }
-}
-
-/**********************************************************************
- * NAME       EXPORTED
- * MmFreeNonCachedMemory at 8
- *
- * DESCRIPTION
- * Releases a range of noncached memory allocated with
- * MmAllocateNonCachedMemory.
- *
- * ARGUMENTS
- * BaseAddress
- *  Virtual address to be freed;
- *
- * NumberOfBytes
- *  Size of the region to be freed.
- *
- * RETURN VALUE
- *  None.
- *
- * NOTE
- *  Description taken from include/ddk/mmfuncs.h.
- *  Code taken from ntoskrnl/mm/special.c.
- *
- * REVISIONS
- *
- * @implemented
- */
-VOID NTAPI MmFreeNonCachedMemory (IN PVOID BaseAddress,
-                                    IN ULONG NumberOfBytes)
-{
-   MmLockAddressSpace(MmGetKernelAddressSpace());
-   MmFreeMemoryAreaByPtr(MmGetKernelAddressSpace(),
-                         BaseAddress,
-                         MmFreeNonCachedPage,
-                         NULL);
-   MmUnlockAddressSpace(MmGetKernelAddressSpace());
-}
-
-/* EOF */

Modified: trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild?rev=41708&r1=41707&r2=41708&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild [iso-8859-1] Tue Jun 30 12:55:18 2009
@@ -367,6 +367,7 @@
 			<file>init.c</file>
 			<file>iosup.c</file>
 			<file>mdlsup.c</file>
+			<file>ncache.c</file>
 			<file>pool.c</file>
 			<file>procsup.c</file>
 			<file>syspte.c</file>
@@ -380,7 +381,6 @@
 		<file>mmsup.c</file>
 		<file>mminit.c</file>
 		<file>mpw.c</file>
-		<file>ncache.c</file>
 		<file>npool.c</file>
 		<file>pagefile.c</file>
 		<file>pageop.c</file>



More information about the Ros-diffs mailing list