Geoff Chappell - Software Analyst
The kernel has long provided lookaside lists for efficient management of memory for the sort of fixed-size structures that the kernel itself and many kernel-mode drivers find themselves allocating and freeing over and over. Some such structures see such heavy use that starting with Windows 2000 the kernel isn’t content with one lookaside list for each type of structure but keeps as many more as there are processors.
For each processor, the kernel has a KPRCB. In version 5.0 and higher, the KPRCB has an array, named PPLookasideList, of 0x10 PP_LOOKASIDE_LIST structures. Each is a pair of pointers, the first to a lookaside list that is specific to that processor, the second to one that is shared among all processors (like any other). The PP_NPAGED_LOOKASIDE_NUMBER enumeration (formally _PP_NPAGED_LOOKASIDE_NUMBER) indexes this array. For each type of structure that is treated to this per-processor optimisation, allocations are sought first from the per-processor list, for speed, else from the shared list. Allocations are freed to the per-processor list for easy re-allocation, except that if the list has reached its capacity the allocation is instead freed to the shared list.
The PP_NPAGED_LOOKASIDE_NUMBER enumeration is not documented. Not even a declaration is known in any kit for device driver programming.
Microsoft’s names for the enumeration’s values are known from type information in public symbol files for the kernel in Windows XP and higher.
Though public symbol files for Windows 2000 (including its service packs) do not show the enumeration, they do name internal routines ExAllocateFromPPNPagedLookasideList and ExFreeToPPNPagedLookasideList. Inspection of the binaries shows that these each take the PP_NPAGED_LOOKASIDE_NUMBER as their first argument. These plausibly were replaced as soon as Windows XP, which slightly reworks the definition of the PP_LOOKASIDE_LIST. If these weren’t already defined as inline routines Also known from the public symbol files, but only starting with Windows 8, is that Microsoft manages the lists through inline routines
PVOID ExAllocateFromPPLookasideList (PP_NPAGED_LOOKASIDE_NUMBER);
VOID ExFreeToPPLookasideList (PP_NPAGED_LOOKASIDE_NUMBER, PVOID, KPRCB *);
|0||LookasideSmallIrpList||5.0 and higher|
|1||LookasideMediumIrpList||6.1 and higher|
|1 (5.0 to 6.0);
|LookasideLargeIrpList||5.0 and higher|
|2 (5.0 to 6.0);
|LookasideMdlList||5.0 and higher|
|3 (5.0 to 6.0);
|LookasideCreateInfoList||5.0 and higher|
|4 (5.0 to 6.0);
|LookasideNameBufferList||5.0 and higher|
|5 (5.0 to 6.0);
|LookasideTwilightList||5.0 and higher|
|6 (5.0 to 6.0);
|LookasideCompletionList||5.0 and higher|
|LookasideScratchBufferList||6.0 and higher|
|7 (5.0 to 5.2);
|LookasideMaximumList||5.0 and higher|