DMA 작업 중 캐시된 데이터 플러시

일부 플랫폼에서는 프로세서 및 시스템 DMA 컨트롤러(또는 버스 master DMA 어댑터)가 캐시 일관성 변칙을 나타냅니다. 다음 지침을 통해 DMA 작업 인터페이스 버전 1 또는 2를 사용하는 드라이버( DMA_OPERATIONS 참조)는 캐시 일관성을 자동으로 적용하는 하드웨어가 포함되지 않은 아키텍처를 포함하여 지원되는 모든 프로세서 아키텍처에서 일관된 캐시 상태를 유지할 수 있습니다.

참고 이 항목의 지침은 DMA 작업 인터페이스 버전 1과 2를 사용하는 드라이버에만 적용됩니다. 이 인터페이스의 버전 3을 사용하는 드라이버는 다른 지침 집합을 따라야 합니다. 자세한 내용은 DMA 작업 인터페이스 버전 3을 참조하세요.

DMA 작업 중 데이터 무결성을 유지하려면 최저 수준 드라이버가 다음 지침을 따라야 합니다.

  1. 전송 작업을 시작하기 전에 KeFlushIoBuffers 를 호출하여 프로세서에 캐시될 수 있는 데이터와 메모리의 데이터 간에 일관성을 유지합니다.

    드라이버가 CacheEnabled 매개 변수가 TRUE로 설정된 AllocateCommonBuffer를 호출하는 경우 드라이버는 버퍼에서 전송 작업을 시작하기 전에 KeFlushIoBuffers를 호출해야 합니다.

  2. 각 디바이스 전송 작업이 끝날 때 FlushAdapterBuffers 를 호출하여 시스템 DMA 컨트롤러 버퍼의 나머지 바이트가 메모리 또는 하위 디바이스에 기록되었는지 확인합니다.

    또는 지정된 IRP에 대한 각 전송 작업이 끝날 때 FlushAdapterBuffers를 호출하여 모든 데이터가 시스템 메모리로 읽혀지거나 버스 master DMA 디바이스에 기록되었는지 확인합니다.

다음 그림에서는 호스트 프로세서와 DMA 컨트롤러가 캐시 일관성을 자동으로 유지 관리하지 않는 경우 DMA를 사용하여 읽기 또는 쓰기 작업 전에 프로세서 캐시를 플러시하는 것이 중요한 이유를 보여 줍니다.

dma를 사용한 읽기 및 쓰기 작업을 보여 주는 다이어그램

비동기 DMA 읽기 또는 쓰기 작업은 프로세서 캐시가 아닌 메모리의 데이터에 액세스합니다. 읽기 직전에 KeFlushIoBuffers 를 호출하여 이 캐시를 플러시하지 않는 한, 프로세서 캐시가 나중에 플러시되는 경우 DMA 작업에서 시스템 메모리로 전송된 데이터를 부실 데이터로 덮어쓸 수 있습니다. 쓰기 직전에 KeFlushIoBuffers 를 호출하여 프로세서 캐시를 플러시하지 않는 한 이 캐시의 데이터는 메모리의 복사본보다 최신 상태일 수 있습니다.

프로세서 및 DMA 컨트롤러를 사용하여 캐시 일관성을 유지할 수 있는 경우 KeFlushIoBuffers는 아무 작업도 수행하지 않으므로 이 지원 루틴에 대한 호출은 이러한 플랫폼에서 거의 오버헤드가 없습니다.

이전 그림과 같이 어댑터 개체로 표시되는 DMA 컨트롤러에는 내부 버퍼가 있을 수 있습니다. 이러한 DMA 컨트롤러는 고정 크기 청크(일반적으로 한 번에 8바이트 이상)로 캐시된 데이터를 전송할 수 있습니다. 또한 이러한 DMA 컨트롤러는 각 전송 작업 전에 내부 버퍼가 가득 찼을 때까지 기다릴 수 있습니다.

하위 DMA를 사용하여 가변 크기 청크 또는 시스템 DMA 컨트롤러 캐시 크기의 정수 배수가 아닌 고정 크기 청크에서 데이터를 읽는 최저 수준 드라이버의 경우를 고려합니다. 이 드라이버가 각 디바이스 전송이 끝날 때 FlushAdapterBuffers 를 호출하지 않는 한 드라이버가 실제로 요청한 모든 바이트가 언제 전송되는지 확신할 수 없습니다.

또한 버스 master DMA 디바이스의 드라이버는 IRP에 대한 각 전송 작업이 끝날 때 FlushAdapterBuffers를 호출하여 모든 데이터가 시스템 메모리 또는 디바이스로 전송되었는지 확인해야 합니다.

FlushAdapterBuffers 는 요청된 플러시 작업이 성공했는지 여부를 나타내는 부울 값을 반환합니다. 드라이버는 이 값을 사용하여 DMA 읽기 또는 쓰기 작업에 대한 IRP를 완료할 때 I/O 상태 블록을 설정하는 방법을 결정할 수 있습니다.