From 9ca493afb59393a430caa89c77e70d8666b031f1 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Fri, 13 May 2005 03:34:13 +0000 Subject: [PATCH] Fix lookaside structures, rewrite lookaside code to use new structures, remove some excess abstraction, correct export incorrectly exported as fastcall, fix up macros, add basic init code to allocate lookaside lists for IRPs as well as per-cpu lookaside lists for irps and completion packets svn path=/trunk/; revision=15254 --- reactos/include/ddk/exfuncs.h | 48 ++-- reactos/include/ddk/extypes.h | 85 +++--- reactos/ntoskrnl/ex/lookas.c | 517 +++++++++++++--------------------- reactos/ntoskrnl/io/iocomp.c | 9 - reactos/ntoskrnl/io/iomgr.c | 129 ++++++++- reactos/ntoskrnl/ntoskrnl.def | 2 +- 6 files changed, 391 insertions(+), 399 deletions(-) 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