본문으로 건너뛰기
PCIe Deep Dive · 11/19

Ch 11: DMA·IOMMU — Coherent·Streaming·ATS·PRI·PASID·IOMMUFD

· Hawk · 8분 읽기

#한 줄 요약

“PCIe DMA는 device가 메모리에 직접 R/W하는 메커니즘이고, IOMMUdevice IOVA → host PA translation·isolation·access control을 책임집니다.” — Linux는 *DMA API (coherent·streaming)*와 *IOMMU subsystem (Intel VT-d·AMD-Vi·ARM SMMU)*를 통합. ATS·PRI·PASID가 *SVM (Shared Virtual Memory)*의 토대고, *IOMMUFD (kernel 6.6+)*가 차세대 userspace IOMMU API입니다.

Ch 5 Interrupts에서 Interrupt Remapping이 IOMMU 한 가지 책임임을 봤습니다. 이 장은 DMA 자체와 IOMMU 전체 그림을 본격적으로 분해합니다.

#DMA API — 2 가지 모델

Model사용
Coherent DMA (dma_alloc_coherent)작은 영구 buffer, cache coherency 자동
Streaming DMA (dma_map_single·dma_map_sg)큰·일회성 buffer, 명시적 sync
// Coherent — descriptor·doorbell buffer
struct desc *ring;
dma_addr_t ring_dma;
ring = dma_alloc_coherent(&pdev->dev, RING_SIZE,
&ring_dma, GFP_KERNEL);
// Streaming — packet payload, ZC I/O
dma_addr_t dma = dma_map_single(&pdev->dev, skb->data,
skb->len, DMA_TO_DEVICE);
// ... HW가 DMA 진행 ...
dma_unmap_single(&pdev->dev, dma, skb->len, DMA_TO_DEVICE);

Coherent작고 자주 access. Streaming큰 transfer. Scatter-gathernon-contiguous physical pages 묶기.

#Cache Coherency

HardwareCoherent DMA
x86DDIO·snoop — 자동 coherent
ARM (no SMMU CCI)비coherent — driver가 cache flush
RISC-V (제한적)DMA coherent 영역 분리

Streaming DMAdirection에 따라 flush/invalidate:

DirectionMap 시Unmap 시
TO_DEVICECPU cache flushnothing
FROM_DEVICEnothingCPU cache invalidate
BIDIRECTIONALflush·invalidateinvalidate·flush

#IOMMU 개요

기능설명
TranslationDevice IOVA → Host PA
IsolationDevice가 허락된 PA만 access
Interrupt RemappingCh 5
Page faultsPRI 처리
PASIDProcess별 다른 address space

벤더 구현:

HardwareIOMMU
IntelVT-d (Virtualization Technology for Directed I/O)
AMDAMD-Vi (IOMMU)
ARMSMMU v2·v3

#IOMMU Group

*동일 IOMMU 그룹 내 device들은 분리 불가. *ACS (Access Control Services)*가 그룹 분리 가능 여부 결정:

시나리오결과
Device 단독 group완전 분리 — VFIO·pass-through 가능
여러 device 한 group그룹 전체가 host 또는 guest 한쪽
Switch port가 ACS 미지원downstream device들이 한 group

/sys/kernel/iommu_groups/그룹 구성 확인. lspci -vv | grep ACSACS capability 확인.

#ATS — Address Translation Services

Device가 직접 translation cache 보유:

시나리오동작
ATS 없음모든 DMA가 IOMMU page walk → latency
ATS 있음Device가 IOVA→PA translation을 미리 받아 cache → DMA 빠름

ATS Extended Cap (0x0026). NIC·NVMe·GPU 같은 high-throughput device큰 latency 절약.

#PRI — Page Request Interface

Device가 page fault 요청:

시나리오동작
Device가 swap-out된 page에 accessPRI 요청 send
OS가 page fault handler 처리 (page-in)success response
OS가 fail (e.g., 권한)error response

SVM의 demand paging 핵심 — process가 swap된 page 있어도 device 동작 정상.

#PASID — Process Address Space ID

20-bit ID로 process별 다른 IOVA → PA mapping:

시나리오효과
PASID 없음Device가 한 address space
PASID 있음DMA에 PASID 표시, IOMMU가 다른 page table 참조

ATS + PRI + PASID 묶음이 SVM (Shared Virtual Memory). Process의 virtual address그대로 device IOVA로 동작. unified address spaceGPU·NPU·smart NIC에서 큰 productivity 향상.

#SVM 흐름

단계동작
1Process가 PASID 할당받음
2Process가 user-mode 메모리 buffer 준비 (mmap)
3Device에 buffer 주소 (process VA) + PASID 전달
4Device가 PASID 표시한 DMA send
5IOMMU가 PASID page table에서 translationpage fault 시 PRI

NVIDIA Grace Hopper UMA·Intel Tile·Sapphire Rapids가 SVM 기반.

#swiotlb — Bounce Buffer

IOMMU 없거나 32-bit DMA mask devicefallback:

시나리오동작
Device DMA mask < 가능 PA rangeswiotlb로 낮은 영역 buffer에 copy
32-bit only NIC + 64-bit systemswiotlb 거쳐 DMA

Performance overhead 큼. 대부분 현대 64-bit device는 swiotlb 미사용.

#IOMMUFD — 차세대 IOMMU userspace API (kernel 6.6+)

기존 VFIO containerIOMMUFD가 대체:

객체의미
ioas (I/O Address Space)guest IOVA space
hwpt (Hardware Page Table)실 page table object
devicebound device

file descriptor: /dev/iommu·/dev/vfio/devices/vfioN. kernel 6.6+에서 stable, VFIO compat shim도 제공. vIOMMU·SR-IOV·S-IOV 모두 IOMMUFD 위에서 통합.

#Linux DMA mask

// 64-bit DMA 지원 device
dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
// 또는 32-bit only
dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));

mask에 따라 어떤 PA rangedevice가 access 가능한지 표시. 부적절하면 swiotlb로 fallback.

#자주 하는 실수

#”Coherent DMA가 항상 빠름”

Coherent bufferuncached 또는 SMMU translation. Random accessstreaming + cache-friendly보다 느릴 수 있음. 큰 transfer는 streaming이 일반.

#”Streaming DMA은 unmap 안 해도 OK”

Unmap이 cache invalidate trigger. Skip 하면 stale data read. 반드시 unmap.

#”ATS 있으면 IOMMU 안 쓴다”

ATS는 translation cache만 device에. IOMMU page table은 여전히 host. cache invalidation도 host가 trigger.

#”PASID 활성하면 자동 SVM”

kernel·driver·device 모두 PASID 인식해야. Process 측 mmap + PASID alloc, Driver의 PASID bind, Device의 PASID-aware DMA 모두 통합 필요.

#”IOMMUFD가 VFIO 즉시 대체”

kernel 6.6+에서 stable하지만 *userspace tooling (QEMU·libvirt)*가 점진적 마이그레이션. 현재 VFIO compat shim으로 둘 다 동작.

#정리

  • *Coherent (작고 영구)·Streaming (크고 일회성)*가 Linux DMA의 2 모델.
  • Cache coherencyx86 자동, ARM 명시 flush·invalidate.
  • IOMMUtranslation·isolation·interrupt remapping·page fault·PASID.
  • IOMMU Group분리 최소 단위. ACS가 그룹 분리 가능성 결정.
  • *ATS (translation cache)·PRI (page fault)·PASID (process ID)*가 SVM의 토대.
  • swiotlblegacy device용 bounce buffer. overhead 큼.
  • *IOMMUFD (kernel 6.6+)*가 VFIO container 대체ioas/hwpt/device 모델.

#다음 편

Ch 12: Virtualization I — Pass-through·SR-IOV·VFIO에서 PF/VF·VFIO container·DPDK·SPDKhardware-level virtualization을 본격적으로 분해합니다.

#관련 항목

#시리즈 자료 출처 안내

본 글의 1차 자료·정책은 Ch 1 footer 참고.