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/…
==============================================================================
--- 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…
==============================================================================
--- 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?…
==============================================================================
--- 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?re…
==============================================================================
--- 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