diff --git a/reactos/include/ddk/exfuncs.h b/reactos/include/ddk/exfuncs.h index 6e92038d5dc..58ba35553a4 100644 --- a/reactos/include/ddk/exfuncs.h +++ b/reactos/include/ddk/exfuncs.h @@ -800,15 +800,15 @@ ExAllocateFromNPagedLookasideList ( { PVOID Entry; - Lookaside->TotalAllocates++; - Entry = ExInterlockedPopEntrySList (&Lookaside->ListHead, - &Lookaside->Obsoleted); + Lookaside->L.TotalAllocates++; + Entry = InterlockedPopEntrySList(&Lookaside->L.ListHead); + if (Entry == NULL) { - Lookaside->AllocateMisses++; - Entry = (Lookaside->Allocate)(Lookaside->Type, - Lookaside->Size, - Lookaside->Tag); + Lookaside->L.AllocateMisses++; + Entry = (Lookaside->L.Allocate)(Lookaside->L.Type, + Lookaside->L.Size, + Lookaside->L.Tag); } return Entry; @@ -820,12 +820,13 @@ ExAllocateFromPagedLookasideList( { PVOID Entry; - Lookaside->TotalAllocates++; - Entry = InterlockedPopEntrySList(&Lookaside->ListHead); + Lookaside->L.TotalAllocates++; + Entry = InterlockedPopEntrySList(&Lookaside->L.ListHead); if (Entry == NULL) { - Lookaside->AllocateMisses++; - Entry = (Lookaside->Allocate)(Lookaside->Type, - Lookaside->Size, Lookaside->Tag); + Lookaside->L.AllocateMisses++; + Entry = (Lookaside->L.Allocate)(Lookaside->L.Type, + Lookaside->L.Size, + Lookaside->L.Tag); } return Entry; } @@ -866,17 +867,16 @@ ExFreeToNPagedLookasideList ( IN PVOID Entry ) { - Lookaside->TotalFrees++; - if (ExQueryDepthSList (&Lookaside->ListHead) >= Lookaside->Depth) + Lookaside->L.TotalFrees++; + if (ExQueryDepthSList (&Lookaside->L.ListHead) >= Lookaside->L.Depth) { - Lookaside->FreeMisses++; - (Lookaside->Free)(Entry); + Lookaside->L.FreeMisses++; + (Lookaside->L.Free)(Entry); } else { - ExInterlockedPushEntrySList (&Lookaside->ListHead, - (PSINGLE_LIST_ENTRY)Entry, - &Lookaside->Obsoleted); + InterlockedPushEntrySList(&Lookaside->L.ListHead, + (PSINGLE_LIST_ENTRY)Entry); } } @@ -885,12 +885,12 @@ ExFreeToPagedLookasideList( IN PPAGED_LOOKASIDE_LIST Lookaside, IN PVOID Entry) { - Lookaside->TotalFrees++; - if (ExQueryDepthSList(&Lookaside->ListHead) >= Lookaside->Depth) { - Lookaside->FreeMisses++; - (Lookaside->Free)(Entry); + Lookaside->L.TotalFrees++; + if (ExQueryDepthSList(&Lookaside->L.ListHead) >= Lookaside->L.Depth) { + Lookaside->L.FreeMisses++; + (Lookaside->L.Free)(Entry); } else { - InterlockedPushEntrySList(&Lookaside->ListHead, (PSLIST_ENTRY)Entry); + InterlockedPushEntrySList(&Lookaside->L.ListHead, (PSLIST_ENTRY)Entry); } } diff --git a/reactos/include/ddk/extypes.h b/reactos/include/ddk/extypes.h index de23f8071a7..aac3b791cf2 100644 --- a/reactos/include/ddk/extypes.h +++ b/reactos/include/ddk/extypes.h @@ -173,52 +173,65 @@ typedef union _SLIST_HEADER }; /* now anonymous */ } SLIST_HEADER, *PSLIST_HEADER; +typedef struct _GENERAL_LOOKASIDE +{ + SLIST_HEADER ListHead; + USHORT Depth; + USHORT MaximumDepth; + ULONG TotalAllocates; + union { + ULONG AllocateMisses; + ULONG AllocateHits; + }; + ULONG TotalFrees; + union { + ULONG FreeMisses; + ULONG FreeHits; + }; + POOL_TYPE Type; + ULONG Tag; + ULONG Size; + PALLOCATE_FUNCTION Allocate; + PFREE_FUNCTION Free; + LIST_ENTRY ListEntry; + ULONG LastTotalAllocates; + union { + ULONG LastAllocateMisses; + ULONG LastAllocateHits; + }; + ULONG Future[2]; +} GENERAL_LOOKASIDE, *PGENERAL_LOOKASIDE; + typedef struct _NPAGED_LOOKASIDE_LIST { - SLIST_HEADER ListHead; - USHORT Depth; - USHORT MaximumDepth; - ULONG TotalAllocates; - ULONG AllocateMisses; - ULONG TotalFrees; - ULONG FreeMisses; - POOL_TYPE Type; - ULONG Tag; - ULONG Size; - PALLOCATE_FUNCTION Allocate; - PFREE_FUNCTION Free; - LIST_ENTRY ListEntry; - ULONG LastTotalAllocates; - ULONG LastAllocateMisses; - ULONG Pad[2]; - KSPIN_LOCK Obsoleted; + GENERAL_LOOKASIDE L; + KSPIN_LOCK Lock__ObsoleteButDoNotDelete; } NPAGED_LOOKASIDE_LIST, *PNPAGED_LOOKASIDE_LIST; typedef struct _PAGED_LOOKASIDE_LIST { - SLIST_HEADER ListHead; - USHORT Depth; - USHORT MaximumDepth; - ULONG TotalAllocates; - ULONG AllocateMisses; - ULONG TotalFrees; - ULONG FreeMisses; - POOL_TYPE Type; - ULONG Tag; - ULONG Size; - PALLOCATE_FUNCTION Allocate; - PFREE_FUNCTION Free; - LIST_ENTRY ListEntry; - ULONG LastTotalAllocates; - ULONG LastAllocateMisses; - FAST_MUTEX Obsoleted; + GENERAL_LOOKASIDE L; + FAST_MUTEX Lock__ObsoleteButDoNotDelete; } PAGED_LOOKASIDE_LIST, *PPAGED_LOOKASIDE_LIST; -typedef struct _PP_LOOKASIDE_LIST { - struct _GENERAL_LOOKASIDE *P; - struct _GENERAL_LOOKASIDE *L; +typedef struct _PP_LOOKASIDE_LIST +{ + PGENERAL_LOOKASIDE P; + PGENERAL_LOOKASIDE L; } PP_LOOKASIDE_LIST, *PPP_LOOKASIDE_LIST; +typedef enum _PP_NPAGED_LOOKASIDE_NUMBER +{ + LookasideSmallIrpList = 0, + LookasideLargeIrpList = 1, + LookasideMdlList = 2, + LookasideCreateInfoList = 3, + LookasideNameBufferList = 4, + LookasideTwilightList = 5, + LookasideCompletionList = 6, + LookasideMaximumList = 7 +} PP_NPAGED_LOOKASIDE_NUMBER; + typedef enum _EX_POOL_PRIORITY { LowPoolPriority, LowPoolPrioritySpecialPoolOverrun = 8, diff --git a/reactos/ntoskrnl/ex/lookas.c b/reactos/ntoskrnl/ex/lookas.c index a65d99d2e1d..d0f2aed5587 100644 --- a/reactos/ntoskrnl/ex/lookas.c +++ b/reactos/ntoskrnl/ex/lookas.c @@ -1,19 +1,14 @@ -/* $Id$ - * +/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: ntoskrnl/ex/lookas.c * PURPOSE: Lookaside lists * - * PROGRAMMERS: David Welch (welch@mcmail.com) + * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) + * David Welch (welch@mcmail.com) * Casper S. Hornstrup (chorns@users.sourceforge.net) */ - -/* - * TODO: Use InterlockedXxxEntrySList for binary compatibility - */ - /* INCLUDES *****************************************************************/ #include @@ -24,153 +19,165 @@ LIST_ENTRY ExpNonPagedLookasideListHead; KSPIN_LOCK ExpNonPagedLookasideListLock; - LIST_ENTRY ExpPagedLookasideListHead; KSPIN_LOCK ExpPagedLookasideListLock; -PLOOKASIDE_MINMAX_ROUTINE ExpMinMaxRoutine; - -#define LookasideListLock(l)(&(l->Obsoleted)) - /* FUNCTIONS *****************************************************************/ -static -inline -PSINGLE_LIST_ENTRY - PopEntrySList( - PSLIST_HEADER ListHead - ) -{ - PSINGLE_LIST_ENTRY ListEntry; - - ListEntry = ListHead->Next.Next; - if (ListEntry!=NULL) - { - ListHead->Next.Next = ListEntry->Next; - ListHead->Depth++; - ListHead->Sequence++; - } - return ListEntry; -} - - -static -inline -VOID -PushEntrySList ( - PSLIST_HEADER ListHead, - PSINGLE_LIST_ENTRY Entry - ) -{ - Entry->Next = ListHead->Next.Next; - ListHead->Next.Next = Entry; - ListHead->Depth++; - ListHead->Sequence++; -} - - -VOID ExpDefaultMinMax( - POOL_TYPE PoolType, - ULONG Size, - PUSHORT MinimumDepth, - PUSHORT MaximumDepth) -/* - * FUNCTION: Determines the minimum and maximum depth of a new lookaside list - * ARGUMENTS: - * Type = Type of executive pool - * Size = Size in bytes of each element in the new lookaside list - * MinimumDepth = Buffer to store minimum depth of the new lookaside list in - * MaximumDepth = Buffer to store maximum depth of the new lookaside list in - */ -{ - /* FIXME: Could probably do some serious computing here */ - if ((PoolType == NonPagedPool) || - (PoolType == NonPagedPoolMustSucceed)) - { - *MinimumDepth = 10; - *MaximumDepth = 100; - } - else - { - *MinimumDepth = 20; - *MaximumDepth = 200; - } -} - - -PVOID STDCALL -ExpDefaultAllocate(POOL_TYPE PoolType, - ULONG NumberOfBytes, - ULONG Tag) -/* - * FUNCTION: Default allocate function for lookaside lists - * ARGUMENTS: - * Type = Type of executive pool - * NumberOfBytes = Number of bytes to allocate - * Tag = Tag to use - * RETURNS: - * Pointer to allocated memory, or NULL if there is not enough free resources - */ -{ - return ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag); -} - - -VOID STDCALL -ExpDefaultFree(PVOID Buffer) -/* - * FUNCTION: Default free function for lookaside lists - * ARGUMENTS: - * Buffer = Pointer to memory to free - */ -{ - ExFreePool(Buffer); -} - - -VOID INIT_FUNCTION +VOID +INIT_FUNCTION ExpInitLookasideLists() { - InitializeListHead(&ExpNonPagedLookasideListHead); - KeInitializeSpinLock(&ExpNonPagedLookasideListLock); - - InitializeListHead(&ExpPagedLookasideListHead); - KeInitializeSpinLock(&ExpPagedLookasideListLock); - - /* FIXME: Possibly configure the algorithm using the registry */ - ExpMinMaxRoutine = ExpDefaultMinMax; + /* Initialize Lock and Listhead */ + InitializeListHead(&ExpNonPagedLookasideListHead); + KeInitializeSpinLock(&ExpNonPagedLookasideListLock); + InitializeListHead(&ExpPagedLookasideListHead); + KeInitializeSpinLock(&ExpPagedLookasideListLock); } - +/* + * @implemented + */ PVOID -FASTCALL -ExiAllocateFromPagedLookasideList ( - PPAGED_LOOKASIDE_LIST Lookaside - ) +STDCALL +ExiAllocateFromPagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside) { - PVOID Entry; + PVOID Entry; - /* Try to obtain an entry from the lookaside list. If that fails, try to - allocate a new entry with the allocate method for the lookaside list */ - - Lookaside->TotalAllocates++; - -// ExAcquireFastMutex(LookasideListLock(Lookaside)); - - Entry = PopEntrySList(&Lookaside->ListHead); - -// ExReleaseFastMutex(LookasideListLock(Lookaside)); - - if (Entry) + Lookaside->L.TotalAllocates++; + Entry = InterlockedPopEntrySList(&Lookaside->L.ListHead); + if (!Entry) + { + Lookaside->L.AllocateMisses++; + Entry = (Lookaside->L.Allocate)(Lookaside->L.Type, + Lookaside->L.Size, + Lookaside->L.Tag); + } return Entry; +} - Lookaside->AllocateMisses++; +/* + * @implemented + */ +VOID +STDCALL +ExiFreeToPagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside, + IN PVOID Entry) +{ + Lookaside->L.TotalFrees++; + if (ExQueryDepthSList(&Lookaside->L.ListHead) >= Lookaside->L.Depth) + { + Lookaside->L.FreeMisses++; + (Lookaside->L.Free)(Entry); + } + else + { + InterlockedPushEntrySList(&Lookaside->L.ListHead, (PSLIST_ENTRY)Entry); + } +} - Entry = (*Lookaside->Allocate)(Lookaside->Type, - Lookaside->Size, - Lookaside->Tag); +/* + * @implemented + */ +VOID +STDCALL +ExDeleteNPagedLookasideList(PNPAGED_LOOKASIDE_LIST Lookaside) +{ + KIRQL OldIrql; + PVOID Entry; - return Entry; + /* Pop all entries off the stack and release the resources allocated + for them */ + for (;;) + { + Entry = InterlockedPopEntrySList(&Lookaside->L.ListHead); + if (!Entry) break; + (*Lookaside->L.Free)(Entry); + } + + /* Remove from list */ + KeAcquireSpinLock(&ExpNonPagedLookasideListLock, &OldIrql); + RemoveEntryList(&Lookaside->L.ListEntry); + KeReleaseSpinLock(&ExpNonPagedLookasideListLock, OldIrql); +} + +/* + * @implemented + */ +VOID +STDCALL +ExDeletePagedLookasideList(PPAGED_LOOKASIDE_LIST Lookaside) +{ + KIRQL OldIrql; + PVOID Entry; + + /* Pop all entries off the stack and release the resources allocated + for them */ + for (;;) + { + Entry = InterlockedPopEntrySList(&Lookaside->L.ListHead); + if (!Entry) break; + (*Lookaside->L.Free)(Entry); + } + + /* Remove from list */ + KeAcquireSpinLock(&ExpPagedLookasideListLock, &OldIrql); + RemoveEntryList(&Lookaside->L.ListEntry); + KeReleaseSpinLock(&ExpPagedLookasideListLock, OldIrql); +} + +/* + * @implemented + */ +VOID +STDCALL +ExInitializeNPagedLookasideList(PNPAGED_LOOKASIDE_LIST Lookaside, + PALLOCATE_FUNCTION Allocate, + PFREE_FUNCTION Free, + ULONG Flags, + ULONG Size, + ULONG Tag, + USHORT Depth) +{ + DPRINT("Initializing nonpaged lookaside list at 0x%X\n", Lookaside); + + /* Initialize the Header */ + ExInitializeSListHead(&Lookaside->L.ListHead); + Lookaside->L.TotalAllocates = 0; + Lookaside->L.AllocateMisses = 0; + Lookaside->L.TotalFrees = 0; + Lookaside->L.FreeMisses = 0; + Lookaside->L.Type = NonPagedPool | Flags; + Lookaside->L.Tag = Tag; + Lookaside->L.Size = Size; + Lookaside->L.Depth = 4; + Lookaside->L.MaximumDepth = 256; + Lookaside->L.LastTotalAllocates = 0; + Lookaside->L.LastAllocateMisses = 0; + + /* Set the Allocate/Free Routines */ + if (Allocate) + { + Lookaside->L.Allocate = Allocate; + } + else + { + Lookaside->L.Allocate = ExAllocatePoolWithTag; + } + + if (Free) + { + Lookaside->L.Free = Free; + } + else + { + Lookaside->L.Free = ExFreePool; + } + + /* Insert it into the list */ + ExInterlockedInsertTailList(&ExpNonPagedLookasideListHead, + &Lookaside->L.ListEntry, + &ExpNonPagedLookasideListLock); } @@ -179,199 +186,53 @@ ExiAllocateFromPagedLookasideList ( */ VOID STDCALL -ExDeleteNPagedLookasideList ( - PNPAGED_LOOKASIDE_LIST Lookaside - ) +ExInitializePagedLookasideList (PPAGED_LOOKASIDE_LIST Lookaside, + PALLOCATE_FUNCTION Allocate, + PFREE_FUNCTION Free, + ULONG Flags, + ULONG Size, + ULONG Tag, + USHORT Depth) { - KIRQL OldIrql; - PVOID Entry; + DPRINT("Initializing paged lookaside list at 0x%X\n", Lookaside); - /* Pop all entries off the stack and release the resources allocated - for them */ - while ((Entry = ExInterlockedPopEntrySList( - &Lookaside->ListHead, - LookasideListLock(Lookaside))) != NULL) - { - (*Lookaside->Free)(Entry); - } + /* Initialize the Header */ + ExInitializeSListHead(&Lookaside->L.ListHead); + Lookaside->L.TotalAllocates = 0; + Lookaside->L.AllocateMisses = 0; + Lookaside->L.TotalFrees = 0; + Lookaside->L.FreeMisses = 0; + Lookaside->L.Type = PagedPool | Flags; + Lookaside->L.Tag = Tag; + Lookaside->L.Size = Size; + Lookaside->L.Depth = 4; + Lookaside->L.MaximumDepth = 256; + Lookaside->L.LastTotalAllocates = 0; + Lookaside->L.LastAllocateMisses = 0; - KeAcquireSpinLock(&ExpNonPagedLookasideListLock, &OldIrql); - RemoveEntryList(&Lookaside->ListEntry); - KeReleaseSpinLock(&ExpNonPagedLookasideListLock, OldIrql); -} + /* Set the Allocate/Free Routines */ + if (Allocate) + { + Lookaside->L.Allocate = Allocate; + } + else + { + Lookaside->L.Allocate = ExAllocatePoolWithTag; + } - -/* - * @implemented - */ -VOID -STDCALL -ExDeletePagedLookasideList ( - PPAGED_LOOKASIDE_LIST Lookaside - ) -{ - KIRQL OldIrql; - PVOID Entry; - - /* Pop all entries off the stack and release the resources allocated - for them */ - for (;;) - { - -// ExAcquireFastMutex(LookasideListLock(Lookaside)); - - Entry = PopEntrySList(&Lookaside->ListHead); - if (!Entry) - break; - -// ExReleaseFastMutex(LookasideListLock(Lookaside)); - - (*Lookaside->Free)(Entry); - } - - KeAcquireSpinLock(&ExpPagedLookasideListLock, &OldIrql); - RemoveEntryList(&Lookaside->ListEntry); - KeReleaseSpinLock(&ExpPagedLookasideListLock, OldIrql); -} - - -VOID -STDCALL -ExiFreeToPagedLookasideList ( - PPAGED_LOOKASIDE_LIST Lookaside, - PVOID Entry - ) -{ - Lookaside->TotalFrees++; - - if (ExQueryDepthSList(&Lookaside->ListHead) >= Lookaside->Depth) - { - Lookaside->FreeMisses++; - (*Lookaside->Free)(Entry); - } - else - { -// ExAcquireFastMutex(LookasideListLock(Lookaside)); - PushEntrySList(&Lookaside->ListHead, (PSINGLE_LIST_ENTRY)Entry); -// ExReleaseFastMutex(LookasideListLock(Lookaside)); - } -} - - -/* - * @implemented - */ -VOID -STDCALL -ExInitializeNPagedLookasideList ( - PNPAGED_LOOKASIDE_LIST Lookaside, - PALLOCATE_FUNCTION Allocate, - PFREE_FUNCTION Free, - ULONG Flags, - ULONG Size, - ULONG Tag, - USHORT Depth) -{ - DPRINT("Initializing nonpaged lookaside list at 0x%X\n", Lookaside); - - Lookaside->TotalAllocates = 0; - Lookaside->AllocateMisses = 0; - Lookaside->TotalFrees = 0; - Lookaside->FreeMisses = 0; - Lookaside->Type = NonPagedPool; - Lookaside->Tag = Tag; - - /* We use a field of type SINGLE_LIST_ENTRY as a link to the next entry in - the lookaside list so we must allocate at least sizeof(SINGLE_LIST_ENTRY) */ - if (Size < sizeof(SINGLE_LIST_ENTRY)) - Lookaside->Size = sizeof(SINGLE_LIST_ENTRY); - else - Lookaside->Size = Size; - - if (Allocate) - Lookaside->Allocate = Allocate; - else - Lookaside->Allocate = ExpDefaultAllocate; - - if (Free) - Lookaside->Free = Free; - else - Lookaside->Free = ExpDefaultFree; - - ExInitializeSListHead(&Lookaside->ListHead); - KeInitializeSpinLock(LookasideListLock(Lookaside)); - - /* Determine minimum and maximum number of entries on the lookaside list - using the configured algorithm */ - (*ExpMinMaxRoutine)( - NonPagedPool, - Lookaside->Size, - &Lookaside->Depth, - &Lookaside->MaximumDepth); - - ExInterlockedInsertTailList( - &ExpNonPagedLookasideListHead, - &Lookaside->ListEntry, - &ExpNonPagedLookasideListLock); -} - - -/* - * @implemented - */ -VOID -STDCALL -ExInitializePagedLookasideList ( - PPAGED_LOOKASIDE_LIST Lookaside, - PALLOCATE_FUNCTION Allocate, - PFREE_FUNCTION Free, - ULONG Flags, - ULONG Size, - ULONG Tag, - USHORT Depth - ) -{ - DPRINT("Initializing paged lookaside list at 0x%X\n", Lookaside); - - Lookaside->TotalAllocates = 0; - Lookaside->AllocateMisses = 0; - Lookaside->TotalFrees = 0; - Lookaside->FreeMisses = 0; - Lookaside->Type = PagedPool; - Lookaside->Tag = Tag; - - /* We use a field of type SINGLE_LIST_ENTRY as a link to the next entry in - the lookaside list so we must allocate at least sizeof(SINGLE_LIST_ENTRY) */ - if (Size < sizeof(SINGLE_LIST_ENTRY)) - Lookaside->Size = sizeof(SINGLE_LIST_ENTRY); - else - Lookaside->Size = Size; - - if (Allocate) - Lookaside->Allocate = Allocate; - else - Lookaside->Allocate = ExpDefaultAllocate; - - if (Free) - Lookaside->Free = Free; - else - Lookaside->Free = ExpDefaultFree; - - ExInitializeSListHead(&Lookaside->ListHead); - //ExInitializeFastMutex(LookasideListLock(Lookaside)); - - /* Determine minimum and maximum number of entries on the lookaside list - using the configured algorithm */ - (*ExpMinMaxRoutine)( - PagedPool, - Lookaside->Size, - &Lookaside->Depth, - &Lookaside->MaximumDepth); - - ExInterlockedInsertTailList( - &ExpPagedLookasideListHead, - &Lookaside->ListEntry, - &ExpPagedLookasideListLock); + if (Free) + { + Lookaside->L.Free = Free; + } + else + { + Lookaside->L.Free = ExFreePool; + } + + /* Insert it into the list */ + ExInterlockedInsertTailList(&ExpNonPagedLookasideListHead, + &Lookaside->L.ListEntry, + &ExpNonPagedLookasideListLock); } /* EOF */ diff --git a/reactos/ntoskrnl/io/iocomp.c b/reactos/ntoskrnl/io/iocomp.c index 3590a679df4..3b956357646 100644 --- a/reactos/ntoskrnl/io/iocomp.c +++ b/reactos/ntoskrnl/io/iocomp.c @@ -141,15 +141,6 @@ IopInitIoCompletionImplementation(VOID) ExIoCompletionType->OkayToClose = NULL; ExIoCompletionType->Create = NULL; ExIoCompletionType->DuplicationNotify = NULL; - - /* Initialize the Lookaside List we'll use for packets */ - ExInitializeNPagedLookasideList(&IoCompletionPacketLookaside, - NULL, - NULL, - 0, - sizeof(IO_COMPLETION_PACKET), - IOC_TAG, - 0); } NTSTATUS diff --git a/reactos/ntoskrnl/io/iomgr.c b/reactos/ntoskrnl/io/iomgr.c index 7fbe39ab733..95e119abda4 100644 --- a/reactos/ntoskrnl/io/iomgr.c +++ b/reactos/ntoskrnl/io/iomgr.c @@ -18,6 +18,12 @@ #define TAG_DEVICE_TYPE TAG('D', 'E', 'V', 'T') #define TAG_FILE_TYPE TAG('F', 'I', 'L', 'E') #define TAG_ADAPTER_TYPE TAG('A', 'D', 'P', 'T') +#define IO_LARGEIRP TAG('I', 'r', 'p', 'l') +#define IO_SMALLIRP TAG('I', 'r', 'p', 's') +#define IO_LARGEIRP_CPU TAG('I', 'r', 'p', 'L') +#define IO_SMALLIRP_CPU TAG('I', 'r', 'p', 'S') +#define IOC_TAG TAG('I', 'p', 'c', ' ') +#define IOC_CPU TAG('I', 'p', 'c', 'P') /* DATA ********************************************************************/ @@ -40,6 +46,9 @@ GENERIC_MAPPING IopFileMapping = { static KSPIN_LOCK CancelSpinLock; extern LIST_ENTRY ShutdownListHead; extern KSPIN_LOCK ShutdownListLock; +extern NPAGED_LOOKASIDE_LIST IoCompletionPacketLookaside; +NPAGED_LOOKASIDE_LIST IoLargeIrpLookaside; +NPAGED_LOOKASIDE_LIST IoSmallIrpLookaside; /* INIT FUNCTIONS ************************************************************/ @@ -58,6 +67,123 @@ IoInitShutdownNotification (VOID) KeInitializeSpinLock(&ShutdownListLock); } +VOID +INIT_FUNCTION +IopInitLookasideLists(VOID) +{ + ULONG LargeIrpSize, SmallIrpSize; + ULONG i; + PKPRCB Prcb; + PNPAGED_LOOKASIDE_LIST CurrentList = NULL; + + /* Calculate the sizes */ + LargeIrpSize = sizeof(IRP) + (8 * sizeof(IO_STACK_LOCATION)); + SmallIrpSize = sizeof(IRP) + sizeof(IO_STACK_LOCATION); + + /* Initialize the Lookaside List for Large IRPs */ + ExInitializeNPagedLookasideList(&IoLargeIrpLookaside, + NULL, + NULL, + 0, + LargeIrpSize, + IO_LARGEIRP, + 0); + + /* Initialize the Lookaside List for Small IRPs */ + ExInitializeNPagedLookasideList(&IoSmallIrpLookaside, + NULL, + NULL, + 0, + SmallIrpSize, + IO_SMALLIRP, + 0); + + /* Initialize the Lookaside List for I\O Completion */ + ExInitializeNPagedLookasideList(&IoCompletionPacketLookaside, + NULL, + NULL, + 0, + sizeof(IO_COMPLETION_PACKET), + IOC_TAG, + 0); + + /* Now allocate the per-processor lists */ + for (i = 0; i < KeNumberProcessors; i++) + { + /* Get the PRCB for this CPU */ + Prcb = ((PKPCR)(KPCR_BASE + i * PAGE_SIZE))->Prcb; + DPRINT1("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); + if (CurrentList) + { + /* Initialize the Lookaside List for Large IRPs */ + ExInitializeNPagedLookasideList(CurrentList, + NULL, + NULL, + 0, + LargeIrpSize, + IO_LARGEIRP_CPU, + 0); + } + else + { + CurrentList = &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); + if (CurrentList) + { + /* Initialize the Lookaside List for Large IRPs */ + ExInitializeNPagedLookasideList(CurrentList, + NULL, + NULL, + 0, + SmallIrpSize, + IO_SMALLIRP_CPU, + 0); + } + 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); + if (CurrentList) + { + /* Initialize the Lookaside List for Large IRPs */ + ExInitializeNPagedLookasideList(CurrentList, + NULL, + NULL, + 0, + SmallIrpSize, + IOC_CPU, + 0); + } + else + { + CurrentList = &IoCompletionPacketLookaside; + } + Prcb->PPLookasideList[LookasideCompletionList].P = &CurrentList->L; + } + + DPRINT1("Done allocation\n"); +} + VOID INIT_FUNCTION IoInit (VOID) @@ -220,6 +346,7 @@ IoInit (VOID) IopInitErrorLog(); IopInitTimerImplementation(); IopInitIoCompletionImplementation(); + IopInitLookasideLists(); /* * Create link from '\DosDevices' to '\??' directory @@ -236,7 +363,7 @@ IoInit (VOID) */ PnpInit(); } - + VOID INIT_FUNCTION IoInit2(BOOLEAN BootLog) diff --git a/reactos/ntoskrnl/ntoskrnl.def b/reactos/ntoskrnl/ntoskrnl.def index 2b5148caad2..973ef319b0d 100644 --- a/reactos/ntoskrnl/ntoskrnl.def +++ b/reactos/ntoskrnl/ntoskrnl.def @@ -70,7 +70,7 @@ ExAcquireResourceSharedLite@8 @ExAcquireRundownProtectionEx@8 ExAcquireSharedStarveExclusive@8 ExAcquireSharedWaitForExclusive@8 -@ExAllocateFromPagedLookasideList@4=@ExiAllocateFromPagedLookasideList@4 +ExAllocateFromPagedLookasideList@4=ExiAllocateFromPagedLookasideList@4 ExAllocatePool@8 ExAllocatePoolWithQuota@8 ExAllocatePoolWithQuotaTag@12