큐 및 큐 해제 IRP

I/O 관리자는 멀티태스킹 및 다중 스레드 시스템 내에서 비동기 I/O를 지원하므로 디바이스에 대한 I/O 요청은 특히 다중 프로세서 컴퓨터에서 드라이버가 완료하도록 처리할 수 있는 것보다 더 빠르게 들어올 수 있습니다. 따라서 특정 디바이스에 바인딩된 IRP는 디바이스가 이미 다른 IRP를 처리하는 중일 때 드라이버에서 큐에 대기해야 합니다.

따라서 최저 수준 드라이버에는 다음 중 하나가 필요합니다.

  • I/O 관리자가 호출하여 드라이버가 시스템 제공 IRP 큐에 큐에 대기한 IRP에 대한 I/O 작업을 시작하는 StartIo 루틴입니다( IoStartPacket 참조).

  • 드라이버가 만족할 수 있는 것보다 빠르게 들어오는 IRP를 관리하는 데 사용하는 내부 IRP 큐 및 큐 해제 메커니즘입니다. 드라이버는 디바이스 큐, 상호 잠긴 큐 또는 취소 안전 큐를 사용할 수 있습니다. 자세한 내용은 드라이버 관리 IRP 큐를 참조하세요.

디스패치 루틴에서 가능한 모든 IRP를 충족하고 완료할 수 있는 가장 낮은 수준의 디바이스 드라이버만 StartIo 루틴이 필요하지 않으며 IRP에 대한 드라이버 관리 큐가 필요하지 않습니다.

상위 수준 드라이버에는 StartIo 루틴이 거의 없습니다. 대부분의 중간 드라이버에는 StartIo 루틴이나 내부 큐가 없습니다. 중간 드라이버는 일반적으로 디스패치 루틴에서 유효한 매개 변수가 있는 IRP를 전달하고 IoCompletion 루틴의 모든 IRP에 필요한 후처리를 수행할 수 있습니다.

다음은 일반적으로 IRP에 대한 내부 드라이버 관리 큐를 사용하거나 사용하지 않고 StartIo 루틴을 구현할지 여부를 결정하기 위한 몇 가지 디자인 고려 사항에 대해 설명합니다.

드라이버의 StartIo 루틴

한 번에 하나의 디바이스 I/O 작업만 처리할 수 있는 컴퓨터 주변 디바이스의 경우 디바이스 드라이버는 StartIo 루틴을 구현할 수 있습니다. 이러한 드라이버의 경우 I/O 관리자는 IoStartPacketIoStartNextPacket 루틴을 제공하여 시스템에서 제공하는 IRP 큐에서 IRP를 큐에 대기시키고 큐에서 제거합니다.

StartIo 루틴에 대한 자세한 내용은 StartIo 루틴 작성을 참조하세요.

드라이버의 IRP에 대한 내부 큐

디바이스가 둘 이상의 동시 I/O 작업을 지원할 수 있는 경우 가장 낮은 수준의 디바이스 드라이버는 내부 요청 큐를 설정하고 자체 IRP 큐를 관리해야 합니다. 예를 들어 시스템 직렬 드라이버는 전체 이중 직렬 디바이스를 지원하므로 디바이스에서 읽기, 쓰기, 제거 및 대기 작업을 위해 별도의 큐를 유지 관리합니다.

일부 수의 기본 디바이스 드라이버에 요청을 보내는 상위 수준 드라이버는 내부 IRP 큐를 유지할 수도 있습니다. 예를 들어 파일 시스템 드라이버에는 거의 항상 IRP에 대한 내부 큐가 있습니다.

자세한 내용은 드라이버 관리 IRP 큐를 참조하세요.

내부 큐 동기화

디바이스 전용 스레드와 임원 작업자 스레드(대부분의 파일 시스템 드라이버 포함)를 사용하는 최고 수준의 드라이버가 있는 드라이버는 일반적으로 IRP에 대한 자체 큐를 설정합니다. 큐는 드라이버 스레드 또는 드라이버 제공 작업자 스레드 콜백 및 IRP를 처리하는 다른 드라이버 루틴에서 공유됩니다.

자체 큐 구조를 구현하는 드라이버는 큐에 대한 액세스가 동기화되고 취소된 IRP가 큐에서 제거되도록 해야 합니다. 드라이버 작성기에 대해 이 작업을 더 간단하게 만들기 위해 취소 안전 IRP 큐는 IRP 큐를 구현할 때 사용할 수 있는 표준 프레임워크를 제공합니다. 자세한 내용은 Cancel-Safe IRP 큐 를 참조하세요. IRP 큐를 구현하기 위한 기본 방법입니다.

드라이버는 모든 IRP 큐 동기화를 구현하고 논리를 명시적으로 취소할 수도 있습니다. 예를 들어 드라이버는 상호 잠긴 큐를 사용할 수 있습니다. 드라이버의 디스패치 루틴은 인터록된 큐에 IRP를 삽입하고 드라이버에서 만든 스레드 또는 드라이버의 작업자 스레드 콜백은 ExInterlockedXxxList 지원 루틴을 호출하여 제거합니다.

예를 들어 시스템 플로피 컨트롤러 드라이버는 상호 잠긴 큐를 사용합니다. 디바이스 전용 스레드는 다른 디바이스 드라이버의 StartIo 루틴에서 수행하는 것과 동일한 IRP 처리와 다른 디바이스 드라이버의 DpcForIsr 루틴에서 수행하는 것과 동일한 IRP 처리 중 일부를 처리합니다.

드라이버에서 StartIo 루틴이 있는 내부 큐

자체 내부 큐를 관리하는 드라이버는 StartIo 루틴을 가질 수도 있지만 필요하지는 않습니다. 가장 낮은 수준의 디바이스 드라이버는 StartIo 루틴을 사용하거나 자체 IRP 큐를 관리하지만 둘 다 관리하지는 않습니다.

이에 대한 예외는 StartIo 루틴이 있고 IRP의 내부 큐를 관리하는 SCSI 포트 드라이버입니다. I/O 관리자는 SCSI HBA를 나타내는 드라이버에서 만든 디바이스 개체와 연결된 디바이스 큐에서 포트 드라이버의 StartIo 루틴으로 IRP를 큐에 대기합니다. 또한 SCSI 포트 드라이버는 머신의 HBA 기반 SCSI 버스에서 각 대상 디바이스(SCSI 논리 단위에 해당)에 대한 IRP에 대한 디바이스 큐를 설정하고 관리합니다.

SCSI 포트 드라이버는 추가 디바이스 큐를 사용하여 SCSI 버스의 모든 디바이스가 특히 사용량이 많은 경우 LU 관련 큐의 SCSI 클래스 드라이버에서 보낸 IRP를 보관합니다. 실제로 이 드라이버의 추가 LU 관련 디바이스 큐를 사용하면 SCSI 포트 드라이버가 HBA를 통해 다른 유형의 SCSI 디바이스에 대한 작업을 직렬화하면서 해당 HBA의 SCSI 버스에 있는 각 디바이스를 가능한 한 바쁘게 유지할 수 있습니다.