Keep DPC queue size correct
authorDavid Welch <welch@cwcom.net>
Tue, 3 Apr 2001 17:25:50 +0000 (17:25 +0000)
committerDavid Welch <welch@cwcom.net>
Tue, 3 Apr 2001 17:25:50 +0000 (17:25 +0000)
Share section pages with cache if possible
If doing a read direct from disk (not via the cache) don't copy the data
MDL fixes

svn path=/trunk/; revision=1773

reactos/drivers/fs/vfat/rw.c
reactos/ntoskrnl/cc/view.c
reactos/ntoskrnl/include/internal/cc.h
reactos/ntoskrnl/include/internal/io.h
reactos/ntoskrnl/io/buildirp.c
reactos/ntoskrnl/io/page.c
reactos/ntoskrnl/ke/dpc.c
reactos/ntoskrnl/mm/mdl.c
reactos/ntoskrnl/mm/section.c

index 59a0d90..8b0a26e 100644 (file)
@@ -1,5 +1,5 @@
 
-/* $Id: rw.c,v 1.21 2001/03/02 15:59:16 cnettel Exp $
+/* $Id: rw.c,v 1.22 2001/04/03 17:25:50 dwelch Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -174,7 +174,10 @@ VfatReadBigCluster(PDEVICE_EXTENSION DeviceExt,
   /*
    * Copy the data from the cache to the caller
    */
-  memcpy(Destination, BaseAddress + InternalOffset, InternalLength);
+  if (InternalOffset != 0 || !NoCache)
+    {
+      memcpy(Destination, BaseAddress + InternalOffset, InternalLength);
+    }
   if (!NoCache)
     {
       CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, TRUE);
@@ -292,7 +295,10 @@ VfatReadSmallCluster(PDEVICE_EXTENSION DeviceExt,
   /*
    * Copy the data from the cache to the caller
    */
-  memcpy(Destination, BaseAddress + InternalOffset, InternalLength);
+  if (InternalOffset != 0 || !NoCache)
+    {
+      memcpy(Destination, BaseAddress + InternalOffset, InternalLength);
+    }
   if (!NoCache)
     {
       CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, TRUE);
index 26ad366..d7ff32a 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: view.c,v 1.22 2001/03/25 02:34:27 dwelch Exp $
+/* $Id: view.c,v 1.23 2001/04/03 17:25:48 dwelch Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
@@ -64,7 +64,7 @@
 /* GLOBALS *******************************************************************/
 
 #define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
-#define ROUND_DOWN(N, S) (ROUND_UP(N, S) - S)
+#define ROUND_DOWN(N, S) (((N) % (S)) ? ROUND_UP(N, S) - S : N)
 
 #define TAG_CSEG  TAG('C', 'S', 'E', 'G')
 #define TAG_BCB   TAG('B', 'C', 'B', ' ')
@@ -104,42 +104,30 @@ CcReleaseCacheSegment(PBCB Bcb,
    return(STATUS_SUCCESS);
 }
 
-NTSTATUS STDCALL 
-CcRequestCacheSegment(PBCB Bcb,
-                     ULONG FileOffset,
-                     PVOID* BaseAddress,
-                     PBOOLEAN UptoDate,
-                     PCACHE_SEGMENT* CacheSeg)
-/*
- * FUNCTION: Request a page mapping for a BCB
- */
+NTSTATUS
+CcGetCacheSegment(PBCB Bcb,
+                 ULONG FileOffset,
+                 PULONG BaseOffset,
+                 PVOID* BaseAddress,
+                 PBOOLEAN UptoDate,
+                 PCACHE_SEGMENT* CacheSeg)
 {
    KIRQL oldirql;
    PLIST_ENTRY current_entry;
    PCACHE_SEGMENT current;
    ULONG i;
    
-   if ((FileOffset % Bcb->CacheSegmentSize) != 0)
-     {
-       KeBugCheck(0);
-     }
-
-   DPRINT("CcRequestCachePage(Bcb %x, FileOffset %x, BaseAddress %x, "
-         "UptoDate %x, CacheSeg %x)\n", Bcb, FileOffset, BaseAddress,
-         UptoDate, CacheSeg);
-   
    KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
    
    current_entry = Bcb->CacheSegmentListHead.Flink;
    while (current_entry != &Bcb->CacheSegmentListHead)
      {
        current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, ListEntry);
-       if (current->FileOffset == FileOffset)
+       if (current->FileOffset <= FileOffset &&
+           (current->FileOffset + Bcb->CacheSegmentSize) > FileOffset)
          {
-            DPRINT("Found existing segment at %x\n", current);
             current->ReferenceCount++;
             KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
-            DPRINT("Waiting for segment\n");
             KeWaitForSingleObject(&current->Lock,
                                   Executive,
                                   KernelMode,
@@ -148,7 +136,7 @@ CcRequestCacheSegment(PBCB Bcb,
             *UptoDate = current->Valid;
             *BaseAddress = current->BaseAddress;
             *CacheSeg = current;
-            DPRINT("Returning %x (UptoDate %d)\n", current, current->Valid);
+            *BaseOffset = current->FileOffset;
             return(STATUS_SUCCESS);
          }
        current_entry = current_entry->Flink;
@@ -170,7 +158,7 @@ CcRequestCacheSegment(PBCB Bcb,
                      (PMEMORY_AREA*)&current->MemoryArea,
                      FALSE);
    current->Valid = FALSE;
-   current->FileOffset = FileOffset;
+   current->FileOffset = ROUND_DOWN(FileOffset, Bcb->CacheSegmentSize);
    current->Bcb = Bcb;
    KeInitializeEvent(&current->Lock, SynchronizationEvent, FALSE);
    current->ReferenceCount = 1;
@@ -178,6 +166,7 @@ CcRequestCacheSegment(PBCB Bcb,
    *UptoDate = current->Valid;
    *BaseAddress = current->BaseAddress;
    *CacheSeg = current;
+   *BaseOffset = current->FileOffset;
    for (i = 0; i < (Bcb->CacheSegmentSize / PAGESIZE); i++)
      {
        MmCreateVirtualMapping(NULL,
@@ -187,11 +176,35 @@ CcRequestCacheSegment(PBCB Bcb,
      }
    
    
-   DPRINT("Returning %x (BaseAddress %x)\n", current, *BaseAddress);
    
    return(STATUS_SUCCESS);
 }
 
+NTSTATUS STDCALL 
+CcRequestCacheSegment(PBCB Bcb,
+                     ULONG FileOffset,
+                     PVOID* BaseAddress,
+                     PBOOLEAN UptoDate,
+                     PCACHE_SEGMENT* CacheSeg)
+/*
+ * FUNCTION: Request a page mapping for a BCB
+ */
+{
+  ULONG BaseOffset;
+   
+  if ((FileOffset % Bcb->CacheSegmentSize) != 0)
+    {
+      KeBugCheck(0);
+    }
+
+  return(CcGetCacheSegment(Bcb,
+                          FileOffset,
+                          &BaseOffset,
+                          BaseAddress,
+                          UptoDate,
+                          CacheSeg));
+}
+
 STATIC VOID 
 CcFreeCachePage(PVOID Context, PVOID Address, ULONG PhysAddr)
 {
index 40d981f..9acb70a 100644 (file)
@@ -1,7 +1,15 @@
 #ifndef __INCLUDE_INTERNAL_CC_H
-#define __INCLUDE_INTERNAL_CCS_H
-/* $Id: cc.h,v 1.2 2000/12/28 03:38:07 dwelch Exp $ */
+#define __INCLUDE_INTERNAL_CC_H
+/* $Id: cc.h,v 1.3 2001/04/03 17:25:48 dwelch Exp $ */
+#include <ddk/ntifs.h>
 VOID STDCALL
 CcMdlReadCompleteDev (IN       PMDL            MdlChain,
                      IN        PDEVICE_OBJECT  DeviceObject);
+NTSTATUS
+CcGetCacheSegment(PBCB Bcb,
+                 ULONG FileOffset,
+                 PULONG BaseOffset,
+                 PVOID* BaseAddress,
+                 PBOOLEAN UptoDate,
+                 PCACHE_SEGMENT* CacheSeg);
 #endif
index 031729e..989ed6d 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: io.h,v 1.8 2001/01/13 18:38:08 dwelch Exp $
+/* $Id: io.h,v 1.9 2001/04/03 17:25:49 dwelch Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
@@ -86,11 +86,12 @@ VOID IoInitShutdownNotification(VOID);
 VOID IoShutdownRegisteredDevices(VOID);
 VOID IoShutdownRegisteredFileSystems(VOID);
 
-NTSTATUS STDCALL IoPageRead (PFILE_OBJECT              FileObject,
-                            PMDL                       Mdl,
-                            PLARGE_INTEGER             Offset,
-                            PIO_STATUS_BLOCK   StatusBlock,
-                            ULONG PagingIo);
+NTSTATUS STDCALL 
+IoPageRead (PFILE_OBJECT               FileObject,
+           PMDL                        Mdl,
+           PLARGE_INTEGER              Offset,
+           PIO_STATUS_BLOCK    StatusBlock,
+           BOOLEAN PagingIo);
 NTSTATUS STDCALL IoPageWrite (PFILE_OBJECT             FileObject,
                              PMDL                      Mdl,
                              PLARGE_INTEGER            Offset,
index f0b9835..2c57205 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: buildirp.c,v 1.24 2001/03/07 16:48:41 dwelch Exp $
+/* $Id: buildirp.c,v 1.25 2001/04/03 17:25:49 dwelch Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
@@ -481,13 +481,14 @@ IoBuildSynchronousFsdRequest(ULONG MajorFunction,
 }
 
 
-PIRP IoBuildSynchronousFsdRequestWithMdl(ULONG MajorFunction,
-                                        PDEVICE_OBJECT DeviceObject,
-                                        PMDL Mdl,
-                                        PLARGE_INTEGER StartingOffset,
-                                        PKEVENT Event,
-                                        PIO_STATUS_BLOCK IoStatusBlock,
-                                        ULONG PagingIo)
+PIRP 
+IoBuildSynchronousFsdRequestWithMdl(ULONG MajorFunction,
+                                   PDEVICE_OBJECT DeviceObject,
+                                   PMDL Mdl,
+                                   PLARGE_INTEGER StartingOffset,
+                                   PKEVENT Event,
+                                   PIO_STATUS_BLOCK IoStatusBlock,
+                                   BOOLEAN PagingIo)
 /*
  * FUNCTION: Allocates and builds an IRP to be sent synchronously to lower
  * level driver(s)
index 25e37d1..a7e75c5 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: page.c,v 1.11 2001/01/13 18:38:09 dwelch Exp $
+/* $Id: page.c,v 1.12 2001/04/03 17:25:49 dwelch Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
@@ -68,11 +68,12 @@ NTSTATUS STDCALL IoPageWrite(PFILE_OBJECT FileObject,
 }
 
 
-NTSTATUS STDCALL IoPageRead(PFILE_OBJECT FileObject,
-                           PMDL Mdl,
-                           PLARGE_INTEGER Offset,
-                           PIO_STATUS_BLOCK StatusBlock,
-                           ULONG PagingIo)
+NTSTATUS STDCALL 
+IoPageRead(PFILE_OBJECT FileObject,
+          PMDL Mdl,
+          PLARGE_INTEGER Offset,
+          PIO_STATUS_BLOCK StatusBlock,
+          BOOLEAN PagingIo)
 {
    PIRP Irp;
    KEVENT Event;
index c086279..8629257 100644 (file)
@@ -18,7 +18,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: dpc.c,v 1.20 2001/04/02 04:07:49 phreak Exp $
+/* $Id: dpc.c,v 1.21 2001/04/03 17:25:49 dwelch Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
@@ -96,7 +96,10 @@ KiDispatchInterrupt(VOID)
    KeRaiseIrql(HIGH_LEVEL, &oldlvl);
    KeAcquireSpinLockAtDpcLevel(&DpcQueueLock);
    current_entry = RemoveHeadList(&DpcQueueHead);
-   DpcQueueSize--;
+   if (current_entry != &DpcQueueHead)
+     {
+       DpcQueueSize--;
+     }
    KeReleaseSpinLockFromDpcLevel(&DpcQueueLock);
    current = CONTAINING_RECORD(current_entry,KDPC,DpcListEntry);
    current->Lock=FALSE;
@@ -110,7 +113,10 @@ KiDispatchInterrupt(VOID)
        KeRaiseIrql(HIGH_LEVEL, &oldlvl);
        KeAcquireSpinLockAtDpcLevel(&DpcQueueLock);
        current_entry = RemoveHeadList(&DpcQueueHead);
-       DpcQueueSize--;
+       if (current_entry != &DpcQueueHead)
+         {
+           DpcQueueSize--;
+         }
        KeReleaseSpinLockFromDpcLevel(&DpcQueueLock);
        current = CONTAINING_RECORD(current_entry,KDPC,DpcListEntry);
        current->Lock=FALSE;
index adda2ae..059eb54 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: mdl.c,v 1.33 2001/03/25 02:34:28 dwelch Exp $
+/* $Id: mdl.c,v 1.34 2001/04/03 17:25:49 dwelch Exp $
  *
  * COPYRIGHT:    See COPYING in the top level directory
  * PROJECT:      ReactOS kernel
@@ -35,7 +35,8 @@ MmGetMdlPageAddress(PMDL Mdl, PVOID Offset)
    return((PVOID)MdlPages[((ULONG)Offset) / PAGESIZE]);
 }
 
-VOID STDCALL MmUnlockPages(PMDL Mdl)
+VOID STDCALL 
+MmUnlockPages(PMDL Mdl)
 /*
  * FUNCTION: Unlocks the physical pages described by a given MDL
  * ARGUMENTS:
@@ -92,6 +93,11 @@ PVOID STDCALL MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode)
    NTSTATUS Status;
    
    DPRINT("MmMapLockedPages(Mdl %x, AccessMode %x)\n", Mdl, AccessMode);
+
+   if (Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL)
+     {
+       return(Mdl->MappedSystemVa);
+     }
    
    MmLockAddressSpace(MmGetKernelAddressSpace());
    
@@ -131,7 +137,8 @@ PVOID STDCALL MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode)
 }
 
 
-VOID STDCALL MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl)
+VOID STDCALL 
+MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl)
 /*
  * FUNCTION: Releases a mapping set up by a preceding call to MmMapLockedPages
  * ARGUMENTS:
@@ -140,6 +147,16 @@ VOID STDCALL MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl)
  */
 {
    DPRINT("MmUnmapLockedPages(BaseAddress %x, Mdl %x)\n", Mdl, BaseAddress);
+
+   /*
+    * In this case, the MDL has the same system address as the base address
+    * so there is no need to free it
+    */
+   if (Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL)
+     {
+       return;
+     }
+
    MmLockAddressSpace(MmGetKernelAddressSpace());
    (VOID)MmFreeMemoryArea(MmGetKernelAddressSpace(),
                          BaseAddress - Mdl->ByteOffset,
@@ -152,7 +169,8 @@ VOID STDCALL MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl)
 }
 
 
-VOID MmBuildMdlFromPages(PMDL Mdl, PULONG Pages)
+VOID 
+MmBuildMdlFromPages(PMDL Mdl, PULONG Pages)
 {
    ULONG i;
    PULONG MdlPages;
@@ -286,7 +304,8 @@ ULONG STDCALL MmSizeOfMdl (PVOID    Base,
 }
 
 
-VOID STDCALL MmBuildMdlForNonPagedPool (PMDL   Mdl)
+VOID STDCALL 
+MmBuildMdlForNonPagedPool (PMDL        Mdl)
 /*
  * FUNCTION: Fills in the corresponding physical page array of a given 
  * MDL for a buffer in nonpaged system space
@@ -296,8 +315,9 @@ VOID STDCALL MmBuildMdlForNonPagedPool (PMDL        Mdl)
  */
 {
    int va;
-   Mdl->MdlFlags = Mdl->MdlFlags | MDL_SOURCE_IS_NONPAGED_POOL;
-   for (va=0; va<Mdl->Size; va++)
+   Mdl->MdlFlags = Mdl->MdlFlags | 
+     (MDL_SOURCE_IS_NONPAGED_POOL | MDL_PAGES_LOCKED);
+   for (va=0; va < ((Mdl->Size - sizeof(MDL)) / sizeof(ULONG)); va++)
      {
         ((PULONG)(Mdl + 1))[va] =
             (MmGetPhysicalAddress(Mdl->StartVa + (va * PAGESIZE))).u.LowPart;
@@ -306,9 +326,10 @@ VOID STDCALL MmBuildMdlForNonPagedPool (PMDL       Mdl)
 }
 
 
-PMDL STDCALL MmCreateMdl (PMDL MemoryDescriptorList,
-                         PVOID Base,
-                         ULONG Length)
+PMDL STDCALL 
+MmCreateMdl (PMDL      MemoryDescriptorList,
+            PVOID      Base,
+            ULONG      Length)
 /*
  * FUNCTION: Allocates and initalizes an MDL
  * ARGUMENTS:
@@ -337,8 +358,8 @@ PMDL STDCALL MmCreateMdl (PMDL      MemoryDescriptorList,
    return(MemoryDescriptorList);
 }
 
-
-VOID STDCALL MmMapMemoryDumpMdl (PVOID Unknown0)
+VOID STDCALL 
+MmMapMemoryDumpMdl (PVOID      Unknown0)
 /*
  * FIXME: Has something to do with crash dumps. Do we want to implement
  * this?
index 679c42a..672dba7 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: section.c,v 1.54 2001/03/30 15:14:53 dwelch Exp $
+/* $Id: section.c,v 1.55 2001/04/03 17:25:49 dwelch Exp $
  *
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/mm/section.c
@@ -35,6 +35,7 @@
 #include <internal/io.h>
 #include <internal/ps.h>
 #include <internal/pool.h>
+#include <internal/cc.h>
 #include <ddk/ntifs.h>
 
 #define NDEBUG
@@ -248,6 +249,98 @@ MmUnsharePageEntrySectionSegment(PMM_SECTION_SEGMENT Segment,
   MmSetPageEntrySectionSegment(Segment, Offset, Entry);
 }
 
+NTSTATUS
+MiReadPage(PMEMORY_AREA MemoryArea,
+          PLARGE_INTEGER Offset,
+          PVOID* Page)
+{
+  IO_STATUS_BLOCK IoStatus;
+  PFILE_OBJECT FileObject;
+  PMDL Mdl;
+  NTSTATUS Status;
+  PREACTOS_COMMON_FCB_HEADER Fcb;
+
+  FileObject = MemoryArea->Data.SectionData.Section->FileObject;
+  Fcb = (PREACTOS_COMMON_FCB_HEADER)FileObject->FsContext;
+
+  if (FileObject->Flags & FO_DIRECT_CACHE_PAGING_READ &&
+      (Offset->QuadPart % PAGESIZE) == 0)
+    {
+      ULONG BaseOffset;
+      PVOID BaseAddress;
+      BOOLEAN UptoDate;
+      PCACHE_SEGMENT CacheSeg;
+      LARGE_INTEGER SegOffset;
+      PHYSICAL_ADDRESS Addr;
+
+      Status = CcGetCacheSegment(Fcb->Bcb,
+                                (ULONG)Offset->QuadPart,
+                                &BaseOffset,
+                                &BaseAddress,
+                                &UptoDate,
+                                &CacheSeg);
+      if (!NT_SUCCESS(Status))
+       {
+         return(Status);
+       }
+
+      if (!UptoDate)
+       {
+         Mdl = MmCreateMdl(NULL, BaseAddress, Fcb->Bcb->CacheSegmentSize);
+         MmBuildMdlForNonPagedPool(Mdl);
+
+         SegOffset.QuadPart = BaseOffset;
+         Status = IoPageRead(FileObject,
+                             Mdl,
+                             &SegOffset,
+                             &IoStatus,
+                             TRUE);
+         if (!NT_SUCCESS(Status))
+           {
+             CcReleaseCacheSegment(Fcb->Bcb, CacheSeg, FALSE);
+             return(Status);
+           }
+       }
+
+      Addr = MmGetPhysicalAddress(BaseAddress + 
+                                 Offset->QuadPart - BaseOffset);
+      (*Page) = (PVOID)(ULONG)Addr.QuadPart;
+      MmReferencePage((*Page));
+
+      CcReleaseCacheSegment(Fcb->Bcb, CacheSeg, TRUE);
+      return(STATUS_SUCCESS);
+    }
+  else
+    {
+      
+      /*
+       * Allocate a page, this is rather complicated by the possibility
+       * we might have to move other things out of memory
+       */
+      (*Page) = MmAllocPage(0);
+      while ((*Page) == NULL)
+       {
+         MmWaitForFreePages();
+         (*Page) = MmAllocPage(0);
+       }
+      
+      /*
+       * Create an mdl to hold the page we are going to read data into.
+       */
+      Mdl = MmCreateMdl(NULL, NULL, PAGESIZE);
+      MmBuildMdlFromPages(Mdl, (PULONG)Page);
+  
+      /*
+       * Call the FSD to read the page
+       */
+      Status = IoPageRead(FileObject,
+                         Mdl,
+                         Offset,
+                         &IoStatus,
+                         FALSE);
+      return(Status);
+    }
+}
 
 NTSTATUS 
 MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
@@ -256,8 +349,6 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
                             BOOLEAN Locked)
 {
    LARGE_INTEGER Offset;
-   IO_STATUS_BLOCK IoStatus;
-   PMDL Mdl;
    PVOID Page;
    NTSTATUS Status;
    ULONG PAddress;
@@ -461,41 +552,15 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
         * If the entry is zero (and it can't change because we have
         * locked the segment) then we need to load the page.
         */
-       
-       /*
-        * Allocate a page, this is rather complicated by the possibility
-        * we might have to move other things out of memory
-        */
-       Page = MmAllocPage(0);
-       while (Page == NULL)
-         {
-           MmUnlockSectionSegment(Segment);
-           MmUnlockSection(Section);
-           MmUnlockAddressSpace(AddressSpace);
-           MmWaitForFreePages();
-           MmLockAddressSpace(AddressSpace);
-           MmLockSection(Section);
-           MmLockSectionSegment(Segment);
-           Page = MmAllocPage(0);
-         }
-       
-       /*
-        * Create an mdl to hold the page we are going to read data into.
-        */
-       Mdl = MmCreateMdl(NULL, NULL, PAGESIZE);
-       MmBuildMdlFromPages(Mdl, (PULONG)&Page);
-       
+
        /*
         * Release all our locks and read in the page from disk
         */
        MmUnlockSectionSegment(Segment);
        MmUnlockSection(Section);
        MmUnlockAddressSpace(AddressSpace);
-       Status = IoPageRead(MemoryArea->Data.SectionData.Section->FileObject,
-                           Mdl,
-                           &Offset,
-                           &IoStatus,
-                           FALSE);
+
+       Status = MiReadPage(MemoryArea, &Offset, &Page);
        if (!NT_SUCCESS(Status) && Status != STATUS_END_OF_FILE)
          {
             /*