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
This commit is contained in:
Alex Ionescu 2005-05-13 03:34:13 +00:00
parent 5510552add
commit 9ca493afb5
6 changed files with 391 additions and 399 deletions

View file

@ -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);
}
}

View file

@ -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,

View file

@ -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 <ntoskrnl.h>
@ -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 */

View file

@ -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

View file

@ -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)

View file

@ -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