Lookaside 목록 사용
주문형 I/O 작업을 수행하기 위해 고정 크기 버퍼를 동적으로 할당해야 하는 드라이버는 Ex Xxx LookasideListEx 또는 ExXxxLookasideList 지원 루틴을 사용할 수 있습니다. 이러한 드라이버가 lookaside 목록을 초기화한 후 운영 체제는 드라이버의 lookaside 목록에 지정된 크기의 동적으로 할당된 버퍼를 몇 개 보유하여 드라이버에 대해 재사용 가능한 고정 크기 버퍼 집합을 효과적으로 예약합니다. 보기 목록에서 드라이버의 고정 크기 버퍼(항목이라고도 함)의 형식과 내용은 드라이버에 따라 결정됩니다.
예를 들어 기본 SCSI 포트/미니포트 드라이버에 대해 SCSI SRB(요청 블록)를 설정해야 하는 스토리지 클래스 드라이버는 lookaside 목록을 사용합니다. 이러한 클래스 드라이버는 lookaside 목록에서 필요에 따라 SRB에 대한 버퍼를 할당하고, SRB가 완료된 IRP의 클래스 드라이버에 반환될 때마다 다시 사용할 lookaside 목록의 lookaside 목록으로 각 SRB 버퍼를 해제합니다. 스토리지 클래스 드라이버는 드라이버에 대한 I/O 수요가 증가하고 감소하기 때문에 언제든지 사용해야 하는 SRB 수를 미리 정할 수 없으므로 lookaside 목록은 이러한 드라이버에서 고정 크기 SRB에 대한 버퍼 할당 및 할당을 관리하는 편리하고 경제적인 방법입니다.
운영 체제는 현재 사용 중인 모든 페이징 및 비페이징된 lookaside 목록에 대한 상태를 유지 관리하며, 모든 목록의 항목 할당 및 할당 취소에 대한 수요를 동적으로 추적하고 새 항목에 사용할 수 있는 시스템 풀을 추적합니다. 할당에 대한 수요가 높으면 운영 체제는 각 lookaside 목록에 보유하는 항목 수를 늘립니다. 수요가 다시 감소하면 잉여 조회 항목을 다시 시스템 풀로 해제합니다.
Lookaside 목록은 스레드로부터 안전합니다. lookaside 목록에는 드라이버에서 동시에 실행되는 여러 스레드가 lookaside 목록을 공유할 수 있도록 기본 제공 동기화가 있습니다. 이러한 스레드는 공유 lookaside 목록에서 버퍼를 안전하게 할당하고 드라이버가 이러한 작업을 명시적으로 동기화할 필요 없이 이러한 버퍼를 목록으로 해제할 수 있습니다. 그러나 가능한 누수 및 데이터 손상을 방지하려면 lookaside 목록을 공유하는 스레드 집합이 목록의 초기화 및 삭제를 명시적으로 동기화해야 합니다.
Lookaside 목록 인터페이스
Windows Vista 부터 LOOKASIDE_LIST_EX 구조는 페이징된 버퍼 또는 페이징되지 않은 버퍼를 포함할 수 있는 lookaside 목록을 설명합니다. 드라이버가 이 lookaside 목록에 대한 사용자 지정 할당 및 무료 루틴을 제공하는 경우 이러한 루틴은 프라이빗 컨텍스트를 입력 매개 변수로 받습니다. 드라이버는 이 컨텍스트를 사용하여 lookaside 목록에 대한 개인 데이터를 수집할 수 있습니다. 예를 들어 컨텍스트를 사용하여 목록에 의해 동적으로 할당되고 해제된 목록 항목의 수를 계산할 수 있습니다. 이러한 방식으로 컨텍스트를 사용하는 방법을 보여 주는 코드 예제는 ExInitializeLookasideListEx를 참조하세요.
다음 시스템 제공 루틴은 LOOKASIDE_LIST_EX 구조에 설명된 lookaside 목록을 지원합니다.
Windows 2000 부터 PAGED_LOOKASIDE_LIST 구조는 페이징된 버퍼가 포함된 lookaside 목록을 설명합니다. 드라이버가 이 lookaside 목록에 대한 사용자 지정 할당 및 무료 루틴을 제공하는 경우 이러한 루틴은 프라이빗 컨텍스트를 입력 매개 변수로 수신하지 않습니다. 이러한 이유로 드라이버가 Windows Vista 이상 버전의 Windows에서만 실행되도록 의도된 경우 lookaside 목록에 PAGED_LOOKASIDE_LIST 구조 대신 LOOKASIDE_LIST_EX 구조를 사용하는 것이 좋습니다. 다음 시스템 제공 루틴은 PAGED_LOOKASIDE_LIST 구조에서 설명하는 lookaside 목록을 지원합니다.
ExAllocateFromPagedLookasideList
ExInitializePagedLookasideList
Windows 2000 부터 NPAGED_LOOKASIDE_LIST 구조는 페이지가 없는 버퍼가 포함된 lookaside 목록을 설명합니다. 드라이버가 이 lookaside 목록에 대한 사용자 지정 할당 및 무료 루틴을 제공하는 경우 이러한 루틴은 프라이빗 컨텍스트를 입력 매개 변수로 수신하지 않습니다. 드라이버가 Windows Vista 이상 버전의 Windows에서만 실행되도록 의도된 경우 lookaside 목록에 NPAGED_LOOKASIDE_LIST 구조 대신 LOOKASIDE_LIST_EX 구조를 사용하는 것이 좋습니다. 다음 시스템 제공 루틴은 NPAGED_LOOKASIDE_LIST 구조에서 설명하는 lookaside 목록을 지원합니다.
ExAllocateFromNPagedLookasideList
ExInitializeNPagedLookasideList
구현 지침
LOOKASIDE_LIST_EX 구조를 사용하는 lookaside 목록을 구현하려면 다음 디자인 지침을 따릅니다.
ExInitializeLookasideListEx를 호출하여 lookaside 목록을 설정합니다. 이 호출에서 lookaside 목록의 항목을 페이징할 것인지 아니면 페이징되지 않은 버퍼인지 지정합니다. 드라이버 자체 또는 해당 lookaside 목록 항목을 전달하는 기본 드라이버가 IRQL >= DISPATCH_LEVEL 이러한 항목에 액세스할 수 있는 경우 페이지가 없는 버퍼를 사용합니다. 드라이버의 lookaside 목록 항목에 대한 액세스가 항상 IRQL <= APC_LEVEL 발생하는 경우에만 페이징 버퍼를 사용합니다.
lookaside 목록의 LOOKASIDE_LIST_EX 구조는 목록의 항목이 페이징되었는지 아니면 페이지가 지정되지 않았는지에 관계없이 항상 페이지가 지정되지 않은 시스템 메모리에 있어야 합니다.
성능 향상을 위해 할당 및 할당 취소 루틴이 lookaside 목록 항목에 대해 단순히 할당 및 사용 가능한 메모리 이상을 수행해야 하는 경우가 아니면 할당 및 무료 매개 변수에 대한 NULL 포인터를 ExInitializeLookasideListEx에 전달합니다. 예를 들어 이러한 루틴은 동적으로 할당된 버퍼의 드라이버 사용에 대한 정보를 기록할 수 있습니다.
드라이버 제공 할당 루틴은 ExAllocatePoolWithTag 또는 ExAllocatePoolWithQuotaTag 루틴에 직접 수신하는 입력 매개 변수(PoolType, 태그 및 크기)를 전달하여 새 버퍼를 할당할 수 있습니다.
ExAllocateFromLookasideListEx에 대한 모든 호출에 대해 이전에 할당된 항목이 더 이상 사용되지 않을 때마다 가능한 한 빨리 ExFreeToLookasideListEx에 대한 상호 호출을 수행합니다.
각각 ExAllocatePoolWithTag 및 ExFreePool을 호출하는 것 이상의 작업을 수행하지 않는 할당 및 무료 루틴을 제공하면 프로세서 주기가 낭비됩니다. ExAllocateFromLookasideListEx는 드라이버가 ExInitializeLookasideListEx에 NULL 할당 및 무료 포인터를 전달하면 ExAllocatePoolWithTag 및 ExFreePool에 필요한 호출을 자동으로 수행합니다.
드라이버에서 제공하는 할당 루틴은 페이징된 풀의 항목에 대한 메모리를 할당하여 페이징되지 않은 lookaside 목록에 보관하거나 그 반대의 경우도 마찬가지입니다. 또한 목록이 비어 있지 않으면 ExAllocateFromLookasideListEx에 대한 후속 드라이버 호출이 현재 lookaside 목록에 있는 첫 번째 항목을 반환하므로 고정 크기 항목을 할당해야 합니다. 즉, ExAllocateFromLookasideListEx를 호출하면 지정된 lookaside 목록이 현재 비어 있는 경우에만 드라이버 제공 할당 루틴을 호출합니다. 따라서 ExAllocateFromLookasideListEx에 대한 각 호출에서 반환된 항목은 lookaside 목록의 모든 항목이 고정된 크기인 경우에만 드라이버에 필요한 크기입니다. 드라이버 제공 Allocate 루틴은 풀 태그 값의 변경으로 인해 드라이버의 메모리 사용량을 디버깅하고 추적하기가 더 어려워지므로 드라이버가 원래 ExInitializeLookasideListEx에 전달한 태그 값을 변경하지 않아야 합니다.
목록이 이미 가득 차 있지 않으면 ExFreeToLookasideListEx 저장소에 대한 호출이 이전에 lookaside 목록에 할당되었습니다(즉, 목록에 시스템에서 결정된 최대 항목 수가 포함됨). 성능을 향상시키려면 드라이버는 ExAllocateFromLookasideListEx를 호출할 때마다 가능한 한 빨리 ExFreeToLookasideListEx를 상호 호출해야 합니다. 드라이버가 항목을 lookaside 목록으로 빠르게 해제하면 해당 드라이버의 ExAllocateFromLookasideListEx에 대한 다음 호출은 새 항목에 대한 메모리를 동적으로 할당하는 성능 저하를 초래할 가능성이 훨씬 적습니다.
PAGED_LOOKASIDE_LIST 또는 NPAGED_LOOKASIDE_LIST 구조를 사용하는 lookaside 목록에도 유사한 지침이 적용됩니다.