mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-30 19:26:05 +00:00
- 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). svn path=/trunk/; revision=37191
This commit is contained in:
@@ -80,12 +80,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
|
||||
//
|
||||
@@ -248,11 +242,21 @@ typedef enum _IOP_TRANSFER_TYPE
|
||||
IopOtherTransfer
|
||||
} 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 @@ typedef struct _IO_COMPLETION_PACKET
|
||||
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 @@ IopStartRamdisk(
|
||||
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;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
POBJECT_TYPE IoCompletionType;
|
||||
|
||||
NPAGED_LOOKASIDE_LIST IoCompletionPacketLookaside;
|
||||
GENERAL_LOOKASIDE IoCompletionPacketLookaside;
|
||||
|
||||
GENERIC_MAPPING IopCompletionMapping =
|
||||
{
|
||||
@@ -40,8 +40,7 @@ IopUnloadSafeCompletion(IN PDEVICE_OBJECT DeviceObject,
|
||||
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 @@ IopUnloadSafeCompletion(IN PDEVICE_OBJECT DeviceObject,
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
IopFreeIoCompletionPacket(PIO_COMPLETION_PACKET Packet)
|
||||
IopFreeMiniPacket(PIOP_MINI_COMPLETION_PACKET Packet)
|
||||
{
|
||||
PKPRCB Prcb = KeGetCurrentPrcb();
|
||||
PNPAGED_LOOKASIDE_LIST List;
|
||||
@@ -104,7 +103,7 @@ IopDeleteIoCompletion(PVOID ObjectBody)
|
||||
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 @@ IopDeleteIoCompletion(PVOID ObjectBody)
|
||||
{
|
||||
/* 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 @@ IopDeleteIoCompletion(PVOID ObjectBody)
|
||||
else
|
||||
{
|
||||
/* Use common routine */
|
||||
IopFreeIoCompletionPacket(Packet);
|
||||
IopFreeMiniPacket(Packet);
|
||||
}
|
||||
} while (FirstEntry != CurrentEntry);
|
||||
}
|
||||
@@ -155,7 +154,7 @@ IoSetIoCompletion(IN PVOID IoCompletion,
|
||||
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 @@ IoSetIoCompletion(IN PVOID IoCompletion,
|
||||
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 @@ NtRemoveIoCompletion(IN HANDLE IoCompletionHandle,
|
||||
{
|
||||
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 @@ NtRemoveIoCompletion(IN HANDLE IoCompletionHandle,
|
||||
{
|
||||
/* 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 @@ NtRemoveIoCompletion(IN HANDLE IoCompletionHandle,
|
||||
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 */
|
||||
|
||||
@@ -49,7 +49,6 @@ GENERIC_MAPPING IopFileMapping = {
|
||||
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 KSPIN_LOCK IopTimerLock;
|
||||
|
||||
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 @@ IopInitLookasideLists(VOID)
|
||||
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);
|
||||
128,
|
||||
&ExSystemLookasideListHead);
|
||||
|
||||
/* Now allocate the per-processor lists */
|
||||
/* 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);
|
||||
|
||||
/* Set the Large IRP List */
|
||||
Prcb->PPLookasideList[LookasideLargeIrpList].L = &IoLargeIrpLookaside.L;
|
||||
CurrentList = ExAllocatePoolWithTag(NonPagedPool,
|
||||
sizeof(NPAGED_LOOKASIDE_LIST),
|
||||
IO_LARGEIRP_CPU);
|
||||
/* 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 Large IRPs */
|
||||
ExInitializeNPagedLookasideList(CurrentList,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
LargeIrpSize,
|
||||
IO_LARGEIRP_CPU,
|
||||
64);
|
||||
/* 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
|
||||
{
|
||||
CurrentList = &IoLargeIrpLookaside;
|
||||
Prcb->PPLookasideList[LookasideCompletionList].P = &IoCompletionPacketLookaside;
|
||||
}
|
||||
|
||||
/* Set the Large IRP List */
|
||||
Prcb->PPLookasideList[LookasideLargeIrpList].L = &IoLargeIrpLookaside;
|
||||
if (CurrentList)
|
||||
{
|
||||
/* Initialize the Lookaside List for Large IRPs */
|
||||
ExInitializeSystemLookasideList(CurrentList,
|
||||
NonPagedPool,
|
||||
LargeIrpSize,
|
||||
IO_LARGEIRP_CPU,
|
||||
64,
|
||||
&ExSystemLookasideListHead);
|
||||
Prcb->PPLookasideList[LookasideLargeIrpList].P = CurrentList;
|
||||
CurrentList++;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Prcb->PPLookasideList[LookasideLargeIrpList].P = &IoLargeIrpLookaside;
|
||||
}
|
||||
Prcb->PPLookasideList[LookasideLargeIrpList].P = &CurrentList->L;
|
||||
|
||||
/* 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 = &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);
|
||||
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);
|
||||
Prcb->PPLookasideList[LookasideMdlList].L = &IopMdlLookasideList;
|
||||
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 = &IopMdlLookasideList;
|
||||
}
|
||||
Prcb->PPLookasideList[LookasideMdlList].P = &CurrentList->L;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -419,7 +419,7 @@ IopCompleteRequest(IN PKAPC Apc,
|
||||
{
|
||||
/* 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
|
||||
|
||||
Reference in New Issue
Block a user