← PCIe 상세 목차

Hardware · PCIe detailed manual 06 · Linux v6.18.37

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에 따라 달라집니다.

상세 표
3
검증 행
26
절차
5 checkpoints
기준
PCIe · Linux v6.18.37

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 allocationmemory allocator/driverCPU VA/PA, sizeallocation 성공free 후 device 접근
DMA mappingDMA API/IOMMUDMA addr, direction, attrsmapping 성공/IOMMU PTEunmap 시점 오류
descriptor builddriveraddr/len/flagsownership 전환 전 내용잘못된 endian/stride
publication barrierdriver/architecturedma_wmb 등device가 완전한 descriptor 관찰doorbell이 먼저 보임
bus masteringPCI Command/endpointMASTER bitMemory TLP 발생enable 전 queue 시작
PCIe routingDWC/bridgeRID/address/attributesTLP/AERinbound window/routing 오류
IOMMU translationSMMU/IOMMUstream ID/RID, IOVA→PAfault 없음/PTE hitdomain/RID mismatch
cache visibilityDMA API/coherency fabricsync/barrierCPU/device가 같은 data 관찰stale cacheline
completiondevice/driverstatus/index/MSIqueue entry 회수IRQ만 오고 data 미완료

DMA API direction을 device 관점으로 읽기

DirectionDevice 동작CPU 동작map/sync에서 중요한 것오해
DMA_TO_DEVICEMemory Readbuffer를 준비CPU write가 device에 보이게CPU 기준 'send' 이름만 봄
DMA_FROM_DEVICEMemory Write완료 후 buffer 읽음device write가 CPU에 보이게posted write 완료를 MSI만으로 추정
DMA_BIDIRECTIONAL양방향양방향더 강한 관리 비용모르면 전부 BIDIR 사용
Coherent allocationdescriptor/status 공유일반적으로 별도 sync 불필요ordering barrier는 여전히 필요할 수 있음coherent=순서 자동 보장
Streaming mappingpayload 등map/unmap 또는 syncownership 전환마다 API 준수같은 mapping을 무기한 재사용

IOMMU fault를 queue entry로 되돌리는 항목

Fault field연결할 대상예
Requester/Stream IDPCI BDF와 iommu-map03:00.0 RID
IOVAdescriptor DMA address0x124000000
Access typeDMA direction/TLPwrite fault
Length/pagedescriptor length와 mapped span4KiB boundary
Domain/PASIDdevice/domain/processdefault domain
Timestampdoorbell/completion/IRQ tracequeue entry 127
Reasontranslation/permission/abortwrite permission 없음

IOMMU group은 주소 변환과 다른 격리 경계입니다

VM에 PCIe 장치를 직접 할당할 때는 DMA 주소 변환뿐 아니라 다른 장치와 독립적으로 격리할 수 있는지도 확인합니다. 다기능 장치 내부의 우회 경로, ACS(Access Control Services)가 없는 브리지, PCIe 토폴로지 때문에 격리 단위가 한 BDF(Bus·Device·Function)보다 클 수 있습니다. IOMMU group은 다른 장치들로부터 함께 격리할 수 있는 장치 집합이며, VFIO는 이를 DMA 소유권의 단위로 사용합니다.

Linux v6.18.37의 device cdev·IOMMUFD 경로도 이 제약을 유지합니다. 같은 그룹의 장치를 서로 다른 iommufd_ctx에 연결하거나, 일반 호스트 드라이버와 VFIO 등 서로 다른 DMA 소유자가 나누어 사용할 수 없습니다. 소유권 제약을 어기면 VFIO_DEVICE_BIND_IOMMUFD가 실패합니다. 따라서 BDF 하나와 “IOMMU 활성” 표시만으로 할당이 안전하다고 판단하지 말고, 그룹 구성과 그룹 안의 드라이버 소유권을 함께 확인하십시오. 이 설명은 실제 장치 할당이나 격리 시험을 수행한 결과가 아닙니다.

근거: Linux v6.18.37 VFIO의 Groups, Devices, and IOMMUs·Device cdev. API 객체와 buffer 종료 조건은 SMMU 문맥 수명의 VFIO 절에서 이어서 확인합니다.

VF 생성과 안전한 VM 할당은 다른 단계입니다

SR-IOV에서는 PF 드라이버 또는 sriov_numvfs 인터페이스를 통해 VF 수를 설정할 수 있습니다. 각 VF가 PCI function으로 열거되어 BDF와 설정 공간을 갖는다는 사실과 독립적으로 격리·할당할 수 있다는 사실은 구분해야 합니다. 활성화·할당·사용 중 VF 수 변경은 읽기 전용 관측이 아니며 여기서는 실행하지 않습니다.

할당 검토에서는 VF의 실제 IOMMU group과 드라이버 소유권, PF에 대한 의존성, reset의 영향 범위를 따로 확인합니다. VF라는 이름만으로 독립 reset, 성능 보장 또는 group 분리를 보증할 수 없습니다. 기존 group 제약은 SR-IOV에서도 생략되지 않습니다.

Linux PCI SR-IOV HOWTO · VFIO 격리·소유권 문서. Ferdinand Castelino의 Part 12는 원저자 측 연속 자료로 참고했으며 사용자가 재공유했다고 확인한 기록과 합치지 않습니다. 실제 VF 생성·passthrough 시험 결과는 아닙니다.

그림 1. 「6. Endpoint bus-master DMA를 iATU, IOMMU와 cache 관점에서 분리한다」의 실행 순서왼쪽부터 신호나 데이터를 처리하는 순서를 나타냅니다. 각 단계에서 확인할 항목을 함께 표시했습니다.
01 dma_map/alloc
02 IOVA 획득
03 descriptor 작성
04 dma_wmb
05 doorbell MMIO
06 Endpoint Memory TLP
07 DWC/bridge
08 IOMMU
09 DRAM
10 completion/MSI

실제 검증 절차

순서실행남길 증거판정 목적
1DMA mask와 coherent mask 협상 결과를 저장합니다.device address width 안의 DMA addr32/64bit truncation 배제
2descriptor raw bytes와 driver가 해석한 addr/len/flags를 함께 dump합니다.endianness/stride/ownership 일치구조체 pretty print만 믿지 않음
3doorbell 직전 barrier와 bus-master enable을 trace합니다.descriptor 게시 뒤 device fetchordering 문제 분리
4IOMMU fault의 RID/IOVA를 정확한 queue index로 연결합니다.fault가 해당 mapping span 안에 있음무관한 device fault와 혼합 방지
5IRQ를 끄고 polling completion으로도 data visibility를 확인합니다.DMA 문제와 MSI routing 분리interrupt가 원인인지 결과인지 구분

주의Root Complex의 DWC inbound iATU가 항상 endpoint DMA를 최종 DRAM PA까지 변환한다고 가정하지 않습니다. SoC 통합에 따라 interconnect/SMMU 경로가 다르므로 실제 requester path를 확인합니다.

공개적으로 다시 확인할 수 있는 자료

공개되지 않은 제조사 레지스터나 제품별 오프셋은 추측하지 않았습니다. 아래의 제조사 자료, 아키텍처 문서, Linux v6.18.37 원본으로 확인할 수 있는 내용만 다뤘습니다.

DMA mapping과 DMAengine 전송 시작을 분리합니다

dma_map_single()이나 dma_map_sg()는 장치가 쓸 DMA 주소와 필요한 매핑을 준비합니다. 그것만으로 전송이 시작되지는 않습니다. 주변장치가 별도의 DMA controller를 사용하는 slave DMA에서는 DMAengine 채널 요청·설정, descriptor 준비, 제출, 실행 요청, 완료 확인이 이어집니다. PCIe endpoint가 자기 bus-master 엔진을 직접 구동하는 경로와 구분합니다.

slave scatter-gather 예에서는 dmaengine_get_dma_device(chan)의 device로 SG를 매핑하고, 반환된 매핑 개수와 방향으로 descriptor를 준비합니다. 매핑 오류를 확인하고 전송이 끝날 때까지 매핑을 유지합니다. 나중의 sync 역시 같은 DMA device를 사용합니다. client 주변장치의 device와 실제 DMA controller의 device를 무조건 같은 것으로 가정하지 않습니다.

dmaengine_submit()은 pending queue에 제출하며 성공 cookie와 오류를 확인해야 합니다. 제출한 descriptor는 엔진 소유이므로 포인터를 계속 수정하면 안 됩니다. dma_async_issue_pending()이 대기 작업의 실행을 요청하며, 반환 자체가 완료 통지는 아닙니다. 취소 때도 dmaengine_terminate_async()만 호출하고 버퍼를 해제하지 않습니다. 필요하면 허용된 문맥에서 dmaengine_synchronize()로 진행 중 전송·callback의 종료를 확인한 뒤 반환합니다.

기준: DMA Engine API Guide. 이 글은 API 계약을 대조했으며 특정 DMA controller를 실행·성능 측정하지 않았습니다.

English summary. Mapping does not launch a transfer. For slave DMA, map against the DMA controller device, prepare and submit a descriptor, issue pending work, then confirm completion. Asynchronous termination alone does not make its buffer safe to free.