다음을 통해 공유


DPC 루틴 작성 지침

DpcForIsr 또는 CustomDpc 루틴을 작성할 때 다음 사항에 유의하세요.

  • DpcForIsr 또는 CustomDpc 루틴은 물리적 디바이스 및 드라이버가 유지 관리하는 공유 상태 정보 또는 리소스에 대한 액세스를 동일한 디바이스 또는 메모리 위치에 액세스하는 드라이버의 다른 루틴과 동기화해야 합니다.

    DpcForIsr 또는 CustomDpc 루틴이 ISR과 디바이스 또는 상태를 공유하는 경우 디바이스를 프로그래밍하거나 공유 상태에 액세스하는 드라이버 제공 SynchCritSection 루틴의 주소를 제공하여 KeSynchronizeExecution을 호출해야 합니다. 자세한 내용은 중요 섹션 사용을 참조하세요.

    DpcForIsr 또는 CustomDpc 루틴이 ISR 이외의 루틴을 사용하여 상호 잠긴 큐 또는 타이머 개체와 같은 상태 또는 리소스를 공유하는 경우 드라이버 초기화된 임원 스핀 잠금으로 공유 상태 또는 리소스를 보호해야 합니다. 자세한 내용은 스핀 잠금을 참조하세요.

  • DpcForIsrCustomDpc 루틴은 IRQL = DISPATCH_LEVEL 실행되어 호출할 수 있는 지원 루틴 집합을 제한합니다.

    예를 들어 DpcForIsrCustomDpc 루틴은 페이징 가능한 메모리에 액세스하거나 할당할 수 없으며 커널 디스패처 개체 가 신호 상태로 설정될 때까지 기다릴 수 없습니다. 한편, KeAcquireSpinLock 및 KeReleaseSpinLock보다 빠르게 실행되는 KeAcquireSpinLockAtDpcLevelKeReleaseSpinLockFromDpcLevel을 사용하여 드라이버 의 임원 스핀 잠금을 획득하고 해제할 수 있습니다.

    DPC 루틴은 차단 호출을 수행할 수 없지만 PASSIVE_LEVEL IRQL에서 실행되는 시스템 작업자 스레드 에서 실행할 작업 항목을 큐에 대기시킬 수 있습니다. 작업 항목은 디스패처 개체에서 대기하는 차단 호출을 수행할 수 있습니다. 작업 항목을 큐에 넣기 위해 DpcForIsr 루틴은 일반적으로 IoQueueWorkItem과 같은 루틴을 호출하고 CustomDpc 루틴은 일반적으로 ExQueueWorkItem 루틴을 호출합니다.

  • DpcForIsrCustomDpc 루틴은 일반적으로 디바이스에서 다음 I/O 작업을 시작해야 합니다.

    직접 I/O를 사용하는 가장 낮은 수준의 물리적 디바이스 드라이버의 경우 이 책임에는 SynchCritSection 루틴을 사용하여 드라이버가 IoStartNextPacket을 호출하기 전에 현재 IRP를 충족하기 위해 디바이스가 더 많은 데이터를 전송하도록 프로그래밍하는 작업이 포함될 수 있습니다.

  • DpcForIsrCustomDpc 루틴은 짧은 기간 동안만 실행되어야 하며 작업자 스레드에 가능한 한 많은 처리를 위임해야 합니다.

    DPC 루틴이 프로세서에서 실행되는 동안 모든 스레드는 동일한 프로세서에서 실행되지 않습니다. 큐에 대기하고 실행할 준비가 된 다른 DPC 루틴은 현재 DPC 루틴이 완료될 때까지 실행이 차단될 수 있습니다. 시스템 응답성이 저하되지 않도록 하기 위해 일반적인 DPC 루틴은 호출할 때마다 100 마이크로초 이하로 실행되어야 합니다. 태스크에 100 마이크로초 이상이 필요하고 IRQL에서 DISPATCH_LEVEL 실행해야 하는 경우 DPC 루틴은 100 마이크로초 후에 종료되고 나중에 작업을 완료하기 위해 하나 이상의 CustomTimerDpc 루틴을 예약해야 합니다. CustomTimerDpc 루틴에 대한 자세한 내용은 타이머 개체 및 DPC를 참조하세요.

    DPC 루틴은 DISPATCH_LEVEL 실행해야 하는 작업만 수행한 다음 나머지 인터럽트 관련 작업을 IRQL = PASSIVE_LEVEL 실행되는 스레드에 위임해야 합니다. 예를 들어 DPC 루틴은 시스템 작업자 스레드에서 실행할 작업 항목을 큐에 대기할 수 있습니다.

    실행을 지연하기 위해 KeStallExecutionProcessor 루틴을 호출하는 DPC 루틴은 100 마이크로초 이상의 지연을 지정해서는 안 됩니다.

    WDK의 성능 분석 도구를 사용하여 DPC 루틴의 실행 시간을 평가합니다. Tracelog 도구를 사용하여 DPC 실행 시간을 모니터링하는 예제는 예제 15: DPC/ISR 시간 측정을 참조하세요.

  • 드라이버가 DMA를 사용하고 AdapterControl 루틴이 KeepObject 또는 DeallocateObjectKeepRegisters를 반환하는 경우(따라서 추가 전송 작업을 위해 시스템 DMA 컨트롤러 채널 또는 버스 master 어댑터를 유지함) DpcForIsr 또는 CustomDpc 루틴은 FreeAdapterChannel 또는 FreeMapRegisters를 사용하여 어댑터 개체 또는 맵 레지스터를 해제합니다. 는 현재 IRP를 완료하고 컨트롤을 반환하기 전에 입니다.

  • 가장 낮은 수준의 물리적 디바이스 드라이버가 컨트롤러를 통해 I/O 작업을 연결된 디바이스와 동기화하도록 컨트롤러 개체 를 설정하는 경우 DpcForIsr 또는 CustomDpc 루틴은 현재 IRP를 완료하고 컨트롤을 반환하기 전에 IoFreeController 를 사용하여 컨트롤러 개체를 해제하는 작업을 담당합니다.

  • DpcForIsrCustomDpc 루틴은 일반적으로 지정된 요청을 처리하는 동안 발생한 모든 디바이스 오류를 로깅하고, 필요한 경우 현재 요청을 다시 시도하며, I/O 상태 블록을 설정하고 현재 IRP에 대해 IoCompleteRequest를 호출하는 작업을 담당합니다.

  • 드라이버와 디바이스가 겹치는 I/O 작업을 지원하는 경우 드라이버는 겹치는 I/O 작업을 처리하기 위한 규칙을 따라야 합니다.

  • 모든 드라이버의 DpcForIsr 또는 CustomDpc 루틴은 일반적으로 드라이버가 지원해야 하는 공용 I/O 컨트롤 코드의 하위 집합에 대해서만 I/O 처리를 완료합니다. 특히 DPC 루틴은 다음과 같은 특성으로 디바이스 제어 요청에 대한 작업을 완료합니다.

    • 물리적 디바이스의 상태를 변경하는 요청

    • 물리적 디바이스에 대한 본질적으로 휘발성 정보를 반환해야 하는 요청