노무현 대통령 배너


2006. 12. 22. 13:50

[본문스크랩] DMA 관련 Cache Coherency 고려사항

Cache Coherency 를 고려해야 합니다
외부 디바이스가 DMA 로 시스템 메모리를 읽거나 쓸경우에는 CPU 와 독립적으로 진행됩니다. 따라서 CPU 내의 data cache 와 memory 사이에는 coherency 가 없어지게 됩니다.예를 들어 device -> memory DMA 일경우 DMA 가 끝난후 CPU 가 그 버퍼를 읽을시 CPU 는 디바이스가 보낸 데이터 대신 data cache 에 있던 이전 데이터를 읽게 됩니다.따라서 DMA 에 사용할 버퍼를 allocate 할때에는 단순히 kmalloc() 를 사용하면 안되고 coherent (또는 consistent 라고도 말합니다) 한 allocate 를 사용하여야 합니다.coherent allocate 방법은 여러가지가 있으나 가장 쉬운 방법은 consistent_allocate() 함수로 버퍼를 얻는것입니다. 이 함수 소스를 보면 __ioremap() 함수를 부르는데 여기서 physical memory 를 vm 에 매핑할때 non-cacheable 로 해줍니다.따라서 consistent_allocate() 로 얻어진 주소를 CPU 가 억세스하면 cache 를 bypass 하여 직접 메모리를 억세스하므로 DMA 로 보내진 데이터와 coherent 해집니다.초기화때 한번만 이 함수를 사용하면 되니까 사용하기가 쉽습니다.다른 방법으로는 DMA 버퍼를 kmalloc() 로 allocate 하되 DMA 전송이 끝날때마다 (device->memory 시) 또는 DMA 전송을 시작하기 직전 (memory->device 시) consistent_sync() 함수를 부르는것입니다. 이 함수는 DMA 방향에 따라 cache 를 invalidate 또는 write-back 을 해줍니다.consistent_sync 는 사용하기는 조금 더 복잡하나 non-cached read/write 가 아니므로 CPU 가 DMA 버퍼를 억세스할때 속도가 떨어지지 않습니다.참고로 이전 글에서 consistent_alloc() 에 버그가 있다고 본것 같은데 제 경험으로는 그렇지 않다고 생각됩니다. 2800 의 on-chip DMA 를 사용해 보지는 않았지만 여러 종류의 PCI 카드가 Bus-mastering DMA 로 잘 동작하는것을 확인하였습니다.PCI 의 DMA 함수들인 pci_alloc_consistent(), pci_map_single() 들도 위의 consistent_allocate() 와 consistent_sync() 함수를 사용합니다.