CHAPTER 06
6. Endpoint bus-master DMA를 iATU, IOMMU와 cache 관점에서 분리한다
Endpoint의 DMA engine이 Memory Read/Write TLP를 만들면 requester ID가 Root Port와 IOMMU를 통과합니다. DWC eDMA와 endpoint DMA는 별도 엔진이며, dma_map 결과가 IOVA인지 PA인지도 platform에 따라 달라집니다.
DMA 경로의 소유권
| 단계 | 소유자 | 핵심 상태 | 완료 증거 | 수명 오류 |
|---|---|---|---|---|
| buffer allocation | memory allocator/driver | CPU VA/PA, size | allocation 성공 | free 후 device 접근 |
| DMA mapping | DMA API/IOMMU | DMA addr, direction, attrs | mapping 성공/IOMMU PTE | unmap 시점 오류 |
| descriptor build | driver | addr/len/flags | ownership 전환 전 내용 | 잘못된 endian/stride |
| publication barrier | driver/architecture | dma_wmb 등 | device가 완전한 descriptor 관찰 | doorbell이 먼저 보임 |
| bus mastering | PCI Command/endpoint | MASTER bit | Memory TLP 발생 | enable 전 queue 시작 |
| PCIe routing | DWC/bridge | RID/address/attributes | TLP/AER | inbound window/routing 오류 |
| IOMMU translation | SMMU/IOMMU | stream ID/RID, IOVA→PA | fault 없음/PTE hit | domain/RID mismatch |
| cache visibility | DMA API/coherency fabric | sync/barrier | CPU/device가 같은 data 관찰 | stale cacheline |
| completion | device/driver | status/index/MSI | queue entry 회수 | IRQ만 오고 data 미완료 |
DMA API direction을 device 관점으로 읽기
| Direction | Device 동작 | CPU 동작 | map/sync에서 중요한 것 | 오해 |
|---|---|---|---|---|
| DMA_TO_DEVICE | Memory Read | buffer를 준비 | CPU write가 device에 보이게 | CPU 기준 'send' 이름만 봄 |
| DMA_FROM_DEVICE | Memory Write | 완료 후 buffer 읽음 | device write가 CPU에 보이게 | posted write 완료를 MSI만으로 추정 |
| DMA_BIDIRECTIONAL | 양방향 | 양방향 | 더 강한 관리 비용 | 모르면 전부 BIDIR 사용 |
| Coherent allocation | descriptor/status 공유 | 일반적으로 별도 sync 불필요 | ordering barrier는 여전히 필요할 수 있음 | coherent=순서 자동 보장 |
| Streaming mapping | payload 등 | map/unmap 또는 sync | ownership 전환마다 API 준수 | 같은 mapping을 무기한 재사용 |
IOMMU fault를 queue entry로 되돌리는 항목
| Fault field | 연결할 대상 | 예 |
|---|---|---|
| Requester/Stream ID | PCI BDF와 iommu-map | 03:00.0 RID |
| IOVA | descriptor DMA address | 0x124000000 |
| Access type | DMA direction/TLP | write fault |
| Length/page | descriptor length와 mapped span | 4KiB boundary |
| Domain/PASID | device/domain/process | default domain |
| Timestamp | doorbell/completion/IRQ trace | queue entry 127 |
| Reason | translation/permission/abort | write permission 없음 |
실제 검증 절차
| 순서 | 실행 | 남길 증거 | 판정 목적 |
|---|---|---|---|
| 1 | DMA mask와 coherent mask 협상 결과를 저장합니다. | device address width 안의 DMA addr | 32/64bit truncation 배제 |
| 2 | descriptor raw bytes와 driver가 해석한 addr/len/flags를 함께 dump합니다. | endianness/stride/ownership 일치 | 구조체 pretty print만 믿지 않음 |
| 3 | doorbell 직전 barrier와 bus-master enable을 trace합니다. | descriptor 게시 뒤 device fetch | ordering 문제 분리 |
| 4 | IOMMU fault의 RID/IOVA를 정확한 queue index로 연결합니다. | fault가 해당 mapping span 안에 있음 | 무관한 device fault와 혼합 방지 |
| 5 | IRQ를 끄고 polling completion으로도 data visibility를 확인합니다. | DMA 문제와 MSI routing 분리 | interrupt가 원인인지 결과인지 구분 |
주의Root Complex의 DWC inbound iATU가 항상 endpoint DMA를 최종 DRAM PA까지 변환한다고 가정하지 않습니다. SoC 통합에 따라 interconnect/SMMU 경로가 다르므로 실제 requester path를 확인합니다.
공개적으로 다시 확인할 수 있는 자료
공개되지 않은 vendor register나 integration별 offset을 추측해서 채우지 않았습니다. 아래 제조사 자료, architecture 문서와 Linux v6.18.37 원본에서 다시 확인할 수 있는 범위만 사용했습니다.
Linux v6.18.37 DWC common source
iATU programming, version/capability와 eDMA detection
Linux v6.18.37 DWC host source
ECAM/CFG access, Root Port setup, MSI irqdomain와 host lifecycle
Linux v6.18.37 PCI probe
Vendor ID read, pci_dev 생성, BAR sizing와 bridge scan
Linux v6.18.37 PCI resource assignment
bridge window와 endpoint BAR resource 배치
Linux DWC Devicetree binding
reg/ranges, iATU window 수, lane/speed와 MSI/IOMMU 연결