[ros-diffs] [fireball] 37191: - Use ExInitializeSystemLookasideList instead of ExInitializeNPagedLookasideList for the internal I/O lookaside lists (just as it was done for the Ob lists a couple of months ago). - Optimize lookaside allocation by using one large contiguous buffer instead of fragmented buffers for each CPU. - Use NT structure names instead of ReactOS-only structures. - Fixes some memory corruption issues when doing I/O completion (found by Stefan and winetests).

fireball at svn.reactos.org fireball at svn.reactos.org
Tue Nov 4 22:55:56 CET 2008


Author: fireball
Date: Tue Nov  4 15:55:55 2008
New Revision: 37191

URL: http://svn.reactos.org/svn/reactos?rev=37191&view=rev
Log:
- Use ExInitializeSystemLookasideList instead of ExInitializeNPagedLookasideList for the internal I/O lookaside lists (just as it was done for the Ob lists a couple of months ago).
- Optimize lookaside allocation by using one large contiguous buffer instead of fragmented buffers for each CPU.
- Use NT structure names instead of ReactOS-only structures.
- Fixes some memory corruption issues when doing I/O completion (found by Stefan and winetests).

Modified:
    trunk/reactos/ntoskrnl/include/internal/io.h
    trunk/reactos/ntoskrnl/io/iomgr/iocomp.c
    trunk/reactos/ntoskrnl/io/iomgr/iomgr.c
    trunk/reactos/ntoskrnl/io/iomgr/irp.c

Modified: trunk/reactos/ntoskrnl/include/internal/io.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/io.h?rev=37191&r1=37190&r2=37191&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/io.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/io.h [iso-8859-1] Tue Nov  4 15:55:55 2008
@@ -81,12 +81,6 @@
 #define RD_SYMLINK_CREATE_FAILED 5
 
 //
-// Packet Types when piggybacking on the IRP Overlay
-//
-#define IrpCompletionPacket                             0x1
-#define IrpMiniCompletionPacket                         0x2
-
-//
 // We can call the Ob Inlined API, it's the same thing
 //
 #define IopAllocateMdlFromLookaside                     \
@@ -249,10 +243,20 @@
 } IOP_TRANSFER_TYPE, *PIOP_TRANSFER_TYPE;
 
 //
+// Packet Types when piggybacking on the IRP Overlay
+//
+typedef enum _COMPLETION_PACKET_TYPE
+    {
+    IopCompletionPacketIrp,
+    IopCompletionPacketMini,
+    IopCompletionPacketQuota
+} COMPLETION_PACKET_TYPE, *PCOMPLETION_PACKET_TYPE;
+
+//
 // Special version of the IRP Overlay used to optimize I/O completion
 // by not using up a separate structure.
 //
-typedef struct _IO_COMPLETION_PACKET
+typedef struct _IOP_MINI_COMPLETION_PACKET
 {
     struct
     {
@@ -263,10 +267,11 @@
             ULONG PacketType;
         };
     };
-    PVOID Key;
-    PVOID Context;
-    IO_STATUS_BLOCK IoStatus;
-} IO_COMPLETION_PACKET, *PIO_COMPLETION_PACKET;
+    PVOID KeyContext;
+    PVOID ApcContext;
+    NTSTATUS IoStatus;
+    ULONG_PTR IoStatusInformation;
+} IOP_MINI_COMPLETION_PACKET, *PIOP_MINI_COMPLETION_PACKET;
 
 //
 // I/O Completion Context for IoSetIoCompletionRoutineEx
@@ -1036,7 +1041,7 @@
 extern POBJECT_TYPE IoCompletionType;
 extern PDEVICE_NODE IopRootDeviceNode;
 extern ULONG IopTraceLevel;
-extern NPAGED_LOOKASIDE_LIST IopMdlLookasideList;
+extern GENERAL_LOOKASIDE IopMdlLookasideList;
 extern GENERIC_MAPPING IopCompletionMapping;
 extern GENERIC_MAPPING IopFileMapping;
 extern POBJECT_TYPE _IoFileObjectType;

Modified: trunk/reactos/ntoskrnl/io/iomgr/iocomp.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/iocomp.c?rev=37191&r1=37190&r2=37191&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/iocomp.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/iocomp.c [iso-8859-1] Tue Nov  4 15:55:55 2008
@@ -15,7 +15,7 @@
 
 POBJECT_TYPE IoCompletionType;
 
-NPAGED_LOOKASIDE_LIST IoCompletionPacketLookaside;
+GENERAL_LOOKASIDE IoCompletionPacketLookaside;
 
 GENERIC_MAPPING IopCompletionMapping =
 {
@@ -40,8 +40,7 @@
                         IN PVOID Context)
 {
     NTSTATUS Status;
-    PIO_UNLOAD_SAFE_COMPLETION_CONTEXT UnsafeContext =
-        (PIO_UNLOAD_SAFE_COMPLETION_CONTEXT)Context;
+    PIO_UNLOAD_SAFE_COMPLETION_CONTEXT UnsafeContext = Context;
 
     /* Reference the device object */
     ObReferenceObject(UnsafeContext->DeviceObject);
@@ -61,7 +60,7 @@
 
 VOID
 NTAPI
-IopFreeIoCompletionPacket(PIO_COMPLETION_PACKET Packet)
+IopFreeMiniPacket(PIOP_MINI_COMPLETION_PACKET Packet)
 {
     PKPRCB Prcb = KeGetCurrentPrcb();
     PNPAGED_LOOKASIDE_LIST List;
@@ -104,7 +103,7 @@
     PLIST_ENTRY FirstEntry;
     PLIST_ENTRY CurrentEntry;
     PIRP Irp;
-    PIO_COMPLETION_PACKET Packet;
+    PIOP_MINI_COMPLETION_PACKET Packet;
 
     /* Rundown the Queue */
     FirstEntry = KeRundownQueue(Queue);
@@ -116,14 +115,14 @@
         {
             /* Get the Packet */
             Packet = CONTAINING_RECORD(CurrentEntry,
-                                       IO_COMPLETION_PACKET,
+                                       IOP_MINI_COMPLETION_PACKET,
                                        ListEntry);
 
             /* Go to next Entry */
             CurrentEntry = CurrentEntry->Flink;
 
             /* Check if it's part of an IRP, or a separate packet */
-            if (Packet->PacketType == IrpCompletionPacket)
+            if (Packet->PacketType == IopCompletionPacketIrp)
             {
                 /* Get the IRP and free it */
                 Irp = CONTAINING_RECORD(Packet, IRP, Tail.Overlay.ListEntry);
@@ -132,7 +131,7 @@
             else
             {
                 /* Use common routine */
-                IopFreeIoCompletionPacket(Packet);
+                IopFreeMiniPacket(Packet);
             }
         } while (FirstEntry != CurrentEntry);
     }
@@ -155,7 +154,7 @@
     PKQUEUE Queue = (PKQUEUE)IoCompletion;
     PNPAGED_LOOKASIDE_LIST List;
     PKPRCB Prcb = KeGetCurrentPrcb();
-    PIO_COMPLETION_PACKET Packet;
+    PIOP_MINI_COMPLETION_PACKET Packet;
 
     /* Get the P List */
     List = (PNPAGED_LOOKASIDE_LIST)Prcb->
@@ -194,11 +193,11 @@
     if (Packet)
     {
         /* Set up the Packet */
-        Packet->PacketType = IrpMiniCompletionPacket;
-        Packet->Key = KeyContext;
-        Packet->Context = ApcContext;
-        Packet->IoStatus.Status = IoStatus;
-        Packet->IoStatus.Information = IoStatusInformation;
+        Packet->PacketType = IopCompletionPacketMini;
+        Packet->KeyContext = KeyContext;
+        Packet->ApcContext = ApcContext;
+        Packet->IoStatus = IoStatus;
+        Packet->IoStatusInformation = IoStatusInformation;
 
         /* Insert the Queue */
         KeInsertQueue(Queue, &Packet->ListEntry);
@@ -455,7 +454,7 @@
 {
     LARGE_INTEGER SafeTimeout;
     PKQUEUE Queue;
-    PIO_COMPLETION_PACKET Packet;
+    PIOP_MINI_COMPLETION_PACKET Packet;
     PLIST_ENTRY ListEntry;
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
     NTSTATUS Status = STATUS_SUCCESS;
@@ -517,11 +516,11 @@
         {
             /* Get the Packet Data */
             Packet = CONTAINING_RECORD(ListEntry,
-                                       IO_COMPLETION_PACKET,
+                                       IOP_MINI_COMPLETION_PACKET,
                                        ListEntry);
 
             /* Check if this is piggybacked on an IRP */
-            if (Packet->PacketType == IrpCompletionPacket)
+            if (Packet->PacketType == IopCompletionPacketIrp)
             {
                 /* Get the IRP */
                 Irp = CONTAINING_RECORD(ListEntry,
@@ -539,12 +538,13 @@
             else
             {
                 /* Save values */
-                Key = Packet->Key;
-                Apc = Packet->Context;
-                IoStatus = Packet->IoStatus;
+                Key = Packet->KeyContext;
+                Apc = Packet->ApcContext;
+                IoStatus.Status = Packet->IoStatus;
+                IoStatus.Information = Packet->IoStatusInformation;
 
                 /* Free the packet */
-                IopFreeIoCompletionPacket(Packet);
+                IopFreeMiniPacket(Packet);
             }
 
             /* Enter SEH to write back the values */

Modified: trunk/reactos/ntoskrnl/io/iomgr/iomgr.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/iomgr.c?rev=37191&r1=37190&r2=37191&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/iomgr.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/iomgr.c [iso-8859-1] Tue Nov  4 15:55:55 2008
@@ -49,7 +49,6 @@
 extern LIST_ENTRY ShutdownListHead;
 extern LIST_ENTRY LastChanceShutdownListHead;
 extern KSPIN_LOCK ShutdownListLock;
-extern NPAGED_LOOKASIDE_LIST IoCompletionPacketLookaside;
 extern POBJECT_TYPE IoAdapterObjectType;
 ERESOURCE IopDatabaseResource;
 extern ERESOURCE FileSystemListLock;
@@ -76,9 +75,10 @@
 
 extern PDEVICE_OBJECT IopErrorLogObject;
 
-NPAGED_LOOKASIDE_LIST IoLargeIrpLookaside;
-NPAGED_LOOKASIDE_LIST IoSmallIrpLookaside;
-NPAGED_LOOKASIDE_LIST IopMdlLookasideList;
+GENERAL_LOOKASIDE IoLargeIrpLookaside;
+GENERAL_LOOKASIDE IoSmallIrpLookaside;
+GENERAL_LOOKASIDE IopMdlLookasideList;
+extern GENERAL_LOOKASIDE IoCompletionPacketLookaside;
 
 #if defined (ALLOC_PRAGMA)
 #pragma alloc_text(INIT, IoInitSystem)
@@ -94,143 +94,142 @@
     ULONG LargeIrpSize, SmallIrpSize, MdlSize;
     LONG i;
     PKPRCB Prcb;
-    PNPAGED_LOOKASIDE_LIST CurrentList = NULL;
+    PGENERAL_LOOKASIDE CurrentList = NULL;
 
     /* Calculate the sizes */
     LargeIrpSize = sizeof(IRP) + (8 * sizeof(IO_STACK_LOCATION));
     SmallIrpSize = sizeof(IRP) + sizeof(IO_STACK_LOCATION);
     MdlSize = sizeof(MDL) + (23 * sizeof(PFN_NUMBER));
 
+    /* Initialize the Lookaside List for I\O Completion */
+    ExInitializeSystemLookasideList(&IoCompletionPacketLookaside,
+                                    NonPagedPool,
+                                    sizeof(IOP_MINI_COMPLETION_PACKET),
+                                    IOC_TAG1,
+                                    32,
+                                    &ExSystemLookasideListHead);
+    
     /* Initialize the Lookaside List for Large IRPs */
-    ExInitializeNPagedLookasideList(&IoLargeIrpLookaside,
-                                    NULL,
-                                    NULL,
-                                    0,
+    ExInitializeSystemLookasideList(&IoLargeIrpLookaside,
+                                    NonPagedPool,
                                     LargeIrpSize,
                                     IO_LARGEIRP,
-                                    64);
+                                    64,
+                                    &ExSystemLookasideListHead);
+
 
     /* Initialize the Lookaside List for Small IRPs */
-    ExInitializeNPagedLookasideList(&IoSmallIrpLookaside,
-                                    NULL,
-                                    NULL,
-                                    0,
+    ExInitializeSystemLookasideList(&IoSmallIrpLookaside,
+                                    NonPagedPool,
                                     SmallIrpSize,
                                     IO_SMALLIRP,
-                                    32);
-
-    /* Initialize the Lookaside List for I\O Completion */
-    ExInitializeNPagedLookasideList(&IoCompletionPacketLookaside,
-                                    NULL,
-                                    NULL,
-                                    0,
-                                    sizeof(IO_COMPLETION_PACKET),
-                                    IOC_TAG1,
-                                    32);
+                                    32,
+                                    &ExSystemLookasideListHead);
 
     /* Initialize the Lookaside List for MDLs */
-    ExInitializeNPagedLookasideList(&IopMdlLookasideList,
-                                    NULL,
-                                    NULL,
-                                    0,
+    ExInitializeSystemLookasideList(&IopMdlLookasideList,
+                                    NonPagedPool,
                                     MdlSize,
                                     TAG_MDL,
-                                    128);
-
-    /* Now allocate the per-processor lists */
+                                    128,
+                                    &ExSystemLookasideListHead);
+
+    /* Allocate the global lookaside list buffer */
+    CurrentList = ExAllocatePoolWithTag(NonPagedPool, 
+                                        4 * KeNumberProcessors *
+                                        sizeof(GENERAL_LOOKASIDE),
+                                        TAG_IO);
+    
+    /* Loop all processors */
     for (i = 0; i < KeNumberProcessors; i++)
     {
         /* Get the PRCB for this CPU */
         Prcb = KiProcessorBlock[i];
         DPRINT("Setting up lookaside for CPU: %x, PRCB: %p\n", i, Prcb);
 
+        /* Write IRP credit limit */
+        Prcb->LookasideIrpFloat = 512 / KeNumberProcessors;
+
+        /* Set the I/O Completion List */
+        Prcb->PPLookasideList[LookasideCompletionList].L = &IoCompletionPacketLookaside;
+        if (CurrentList)
+        {
+            /* Initialize the Lookaside List for mini-packets */
+            ExInitializeSystemLookasideList(CurrentList,
+                                            NonPagedPool,
+                                            sizeof(IOP_MINI_COMPLETION_PACKET),
+                                            IO_SMALLIRP_CPU,
+                                            32,
+                                            &ExSystemLookasideListHead);
+            Prcb->PPLookasideList[LookasideCompletionList].P = CurrentList;
+            CurrentList++;
+            
+        }
+        else
+        {
+            Prcb->PPLookasideList[LookasideCompletionList].P = &IoCompletionPacketLookaside;
+        }
+        
         /* Set the Large IRP List */
-        Prcb->PPLookasideList[LookasideLargeIrpList].L = &IoLargeIrpLookaside.L;
-        CurrentList = ExAllocatePoolWithTag(NonPagedPool,
-                                            sizeof(NPAGED_LOOKASIDE_LIST),
-                                            IO_LARGEIRP_CPU);
+        Prcb->PPLookasideList[LookasideLargeIrpList].L = &IoLargeIrpLookaside;
         if (CurrentList)
         {
             /* Initialize the Lookaside List for Large IRPs */
-            ExInitializeNPagedLookasideList(CurrentList,
-                                            NULL,
-                                            NULL,
-                                            0,
+            ExInitializeSystemLookasideList(CurrentList,
+                                            NonPagedPool,
                                             LargeIrpSize,
                                             IO_LARGEIRP_CPU,
-                                            64);
+                                            64,
+                                            &ExSystemLookasideListHead);
+            Prcb->PPLookasideList[LookasideLargeIrpList].P = CurrentList;
+            CurrentList++;
+            
         }
         else
         {
-            CurrentList = &IoLargeIrpLookaside;
-        }
-        Prcb->PPLookasideList[LookasideLargeIrpList].P = &CurrentList->L;
+            Prcb->PPLookasideList[LookasideLargeIrpList].P = &IoLargeIrpLookaside;
+        }
 
         /* Set the Small IRP List */
-        Prcb->PPLookasideList[LookasideSmallIrpList].L = &IoSmallIrpLookaside.L;
-        CurrentList = ExAllocatePoolWithTag(NonPagedPool,
-                                            sizeof(NPAGED_LOOKASIDE_LIST),
-                                            IO_SMALLIRP_CPU);
+        Prcb->PPLookasideList[LookasideSmallIrpList].L = &IoSmallIrpLookaside;
         if (CurrentList)
         {
             /* Initialize the Lookaside List for Small IRPs */
-            ExInitializeNPagedLookasideList(CurrentList,
-                                            NULL,
-                                            NULL,
-                                            0,
+            ExInitializeSystemLookasideList(CurrentList,
+                                            NonPagedPool,
                                             SmallIrpSize,
                                             IO_SMALLIRP_CPU,
-                                            32);
+                                            32,
+                                            &ExSystemLookasideListHead);
+            Prcb->PPLookasideList[LookasideSmallIrpList].P = CurrentList;
+            CurrentList++;
+            
         }
         else
         {
-            CurrentList = &IoSmallIrpLookaside;
-        }
-        Prcb->PPLookasideList[LookasideSmallIrpList].P = &CurrentList->L;
-
-        /* Set the I/O Completion List */
-        Prcb->PPLookasideList[LookasideCompletionList].L = &IoCompletionPacketLookaside.L;
-        CurrentList = ExAllocatePoolWithTag(NonPagedPool,
-                                            sizeof(NPAGED_LOOKASIDE_LIST),
-                                            IO_SMALLIRP_CPU);
+            Prcb->PPLookasideList[LookasideSmallIrpList].P = &IoSmallIrpLookaside;
+        }
+
+        /* Set the MDL Completion List */
+        Prcb->PPLookasideList[LookasideMdlList].L = &IopMdlLookasideList;
         if (CurrentList)
         {
-            /* Initialize the Lookaside List for Large IRPs */
-            ExInitializeNPagedLookasideList(CurrentList,
-                                            NULL,
-                                            NULL,
-                                            0,
-                                            sizeof(IO_COMPLETION_PACKET),
-                                            IO_SMALLIRP_CPU,
-                                            32);
-        }
-        else
-        {
-            CurrentList = &IoCompletionPacketLookaside;
-        }
-        Prcb->PPLookasideList[LookasideCompletionList].P = &CurrentList->L;
-
-        /* Set the MDL Completion List */
-        Prcb->PPLookasideList[LookasideMdlList].L = &IopMdlLookasideList.L;
-        CurrentList = ExAllocatePoolWithTag(NonPagedPool,
-                                            sizeof(NPAGED_LOOKASIDE_LIST),
-                                            TAG_MDL);
-        if (CurrentList)
-        {
             /* Initialize the Lookaside List for MDLs */
-            ExInitializeNPagedLookasideList(CurrentList,
-                                            NULL,
-                                            NULL,
-                                            0,
+            ExInitializeSystemLookasideList(CurrentList,
+                                            NonPagedPool,
                                             SmallIrpSize,
                                             TAG_MDL,
-                                            128);
+                                            128,
+                                            &ExSystemLookasideListHead);
+            
+            Prcb->PPLookasideList[LookasideMdlList].P = CurrentList;
+            CurrentList++;
+            
         }
         else
         {
-            CurrentList = &IopMdlLookasideList;
-        }
-        Prcb->PPLookasideList[LookasideMdlList].P = &CurrentList->L;
+            Prcb->PPLookasideList[LookasideMdlList].P = &IopMdlLookasideList;
+        }
     }
 }
 

Modified: trunk/reactos/ntoskrnl/io/iomgr/irp.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/irp.c?rev=37191&r1=37190&r2=37191&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/irp.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/irp.c [iso-8859-1] Tue Nov  4 15:55:55 2008
@@ -419,7 +419,7 @@
         {
             /* We have an I/O Completion setup... create the special Overlay */
             Irp->Tail.CompletionKey = Key;
-            Irp->Tail.Overlay.PacketType = IrpCompletionPacket;
+            Irp->Tail.Overlay.PacketType = IopCompletionPacketIrp;
             KeInsertQueue(Port, &Irp->Tail.Overlay.ListEntry);
         }
         else



More information about the Ros-diffs mailing list