콘텐츠로 이동

Module 08 — SR-IOV, ATS, P2P, CXL

학습 목표

이 모듈을 마치면:

  • Diagram SR-IOVPF / VF 구조와 OSVF 를 게스트에 직접 노출하는 흐름을 그릴 수 있다.
  • Trace ATS Translation Request → Completion 흐름과 PRI page-fault 처리 cycle 을 추적한다.
  • Apply Peer-to-Peer (P2P) DMA 의 사용 사례 (GPUNIC, NVMe↔GPU) 와 ACS 정책의 영향을 시나리오에 매핑한다.
  • Compare CXL.io vs CXL.cache vs CXL.mem 의 의미와 PCIe 와의 관계를 비교한다.
  • Distinguish MFD (Multi-Function Device) 와 SR-IOV VF목적·생성 시점·권한 세 축으로 구분한다.

사전 지식


1. Why care? — 이 모듈이 왜 필요한가

1.1 시나리오 — 하나의 GPU, 64 VM

당신은 클라우드 운영자. NVIDIA A100 GPU 1 개를 64 VM 에 분할 임대.

순진한 해법: VM 마다 전체 GPU 시간 슬롯 할당. 결과: 95% 시간이 idle — 한 VM 의 inference 작업이 GPU 의 1% 만 사용해도 나머지 99% 시간 동안 다른 VM 차단.

해법: SR-IOV (Single Root I/O Virtualization): - 한 Physical Function (PF) + 64 Virtual Functions (VFs). - 각 VF독립적 BAR + interrupt. - IOMMUVF 별 격리VF 끼리 메모리 안 보임.

결과: 64 VM동시에 GPU다른 부분 사용. Utilization 80%+.

지금까지의 PCIe"한 host 의 한 EP 가 host memory 와 직접 대화" 라는 단일 모델이었습니다. 그런데 modern 데이터센터·AI·cloud 의 워크로드는 그 모델로는 풀리지 않습니다 — ① 한 GPU 를 64 개 VM 이 나눠 써야 하고 (SR-IOV), ② DMA 마다 IOMMU walk 가 일어나면 latency 가 못 견디고 (ATS), ③ NIC RX 가 host memory 거치지 않고 GPU memory 로 바로 들어가야 하며 (P2P), ④ DDR 슬롯이 부족해 메모리를 PCIe 슬롯에 꽂아야 합니다 (CXL).

이 모듈을 건너뛰면 modern PCIe 검증의 절반 이 빠집니다 — VFBAR offset, ATS Invalidate timing, ACS 의 default-block 정책, CXL alternate protocol negotiation 모두 spec 의 별도 절(section)이고, 잘못 알면 silent failure (driver 가 capability 검증 누락 → 동작은 하는데 성능 0) 가 가장 흔합니다. 반대로 이 네 가지 메커니즘을 잡아 두면, lspci -vvvCapabilities: [xxx] Single Root I/O Virtualization 한 줄을 보고 "아, 이 device 는 PFVF 256 개까지 derived BAR 로 expose 가능 + ARI enable 필수" 라고 즉시 해석됩니다.


2. Intuition — 임대 건물 비유와 한 장 그림

💡 한 줄 비유

SR-IOV건물 한 동을 여러 회사에 나눠 임대 (PF = 관리사무소, VF = 각 호실, IOMMU = 출입 통제).
ATS호텔 객실에 미리 키 발급 (IOVA→PA mapping 을 device 가 ATC 에 cache).
P2P같은 층 사무실끼리 직접 통화 (RC 거치지 않고 device ↔ device).
CXLPCIe 위에 공유 메모리·cache 일관성 프로토콜 추가 (같은 cable, 다른 layer).

       Guest VMs (각자 자기 VA 공간)
       ┌─────────┐ ┌─────────┐ ┌─────────┐
       │  VM₀    │ │  VM₁    │ │  VM₂    │
       │ driver  │ │ driver  │ │ driver  │
       └────┬────┘ └────┬────┘ └────┬────┘
            │  guest IOVA   │           │     ← 각 VM 이 자기 view 의 주소 사용
   Hypervisor + IOMMU (BDF + PASID 로 page table 분리)
            │           │           │
   ─ PCIe ──┴───────────┴───────────┴───────────────────────────
            │           │           │
        ┌───▼───┐   ┌───▼───┐   ┌───▼───┐
        │ VF₀   │   │ VF₁   │   │ VF₂   │      ← 각자 BDF + BAR + MSI-X
        │  ATC  │   │  ATC  │   │  ATC  │      ← ATS cache (IOVA → PA)
        └───────┘   └───────┘   └───────┘
            └─────────PF (관리)──────────┘      ← PF 가 VF 생성/삭제 권한
                  │  same silicon
                  ▼ host memory (PA)

왜 이렇게 설계됐는가 — Design rationale

세 가지 요구가 동시에 풀려야 했습니다.

  1. 가상화 효율: VM 마다 emulated NIC 을 쓰면 packet 1개에 VM-Exit 가 수십 번 → line rate 못 채움. 하드웨어가 physical function 을 복제 해서 VM 에 직접 노출 (= SR-IOV).
  2. IOMMU latency: 모든 DMAIOMMU page walk 를 거치면 µs 단위 지연. Device 가 PTW 결과를 자체 cache 에 보관 (= ATS).
  3. CPU-bypass topology: GPUNICRX buffer 를 read 할 때 host memory 를 거치지 않고 RC 만 우회 하면 ~ 10× latency 단축 (= P2P), 단 보안을 위해 명시적 허용 (= ACS).
  4. 메모리 확장: DDR DIMM 슬롯이 부족, PCIe slot 으로 메모리 모듈을 꽂되 CPU 가 자기 메모리처럼 load/store 가능해야 (= CXL.mem).

세 + 한 요구의 교집합이 이 모듈의 4 개 mechanism. 모두 "CPU 의 매개를 줄인다" 라는 한 줄로 정리됩니다.


3. 작은 예 — VMVFATS 로 IOVA 한 개를 번역 받는 한 사이클

가장 단순한 시나리오. SR-IOV NICVF₀ 가 VM₀ 에 패스스루되어 있음. VM₀ 의 driver 가 RX buffer 의 IOVA 0x4000_0000 으로 packet 을 수신하려 함. VF 의 ATC 가 비어 있어 ATS Translation Request 한 번 발생.

   t (ns) │ Actor          │ Event                                      │ TLP type        │ AT field
   ──────┼────────────────┼─────────────────────────────────────────────┼─────────────────┼─────────
     0   │ VM₀ driver     │ post RX desc with IOVA=0x4000_0000          │ (no TLP)        │ —
    50   │ VF₀ HW         │ wire 에서 packet 수신, ATC lookup → miss     │ (no TLP)        │ —
    60   │ VF₀ HW         │ ① ATS Translation Request (IOVA=0x4000_0000,│ MRd-like        │ 01 (TR)
         │                │    PASID=guest₀, BDF=(B,D,F.VF0))            │   "TR Request"  │
   ─── upstream to RC ──▶
   100   │ RC + IOMMU     │ ② IOMMU page walk: guest IOVA → host PA      │ —               │ —
         │                │    PA = 0xABCD_0000                          │                 │
   150   │ RC + IOMMU     │ ③ ATS Translation Completion                 │ CplD-like       │ 10 (Translated)
         │                │    (PA=0xABCD_0000, R/W=both, N=0)           │   "TR Cpl"      │
   ◀──── downstream to VF ───
   200   │ VF₀ HW         │ ④ ATC 에 (0x4000_0000 → 0xABCD_0000) 캐시      │ —               │ —
   210   │ VF₀ HW         │ ⑤ packet 256B 를 PA 로 MWr 송신              │ MWr 4DW         │ 10 (Translated)
         │                │    (이번에는 IOMMU walk 우회)                 │                 │
   ─── upstream to RC ──▶
   260   │ RC             │ ⑥ IOMMU 가 AT=10 (Translated) 확인 → bypass  │ —               │ —
   270   │ Host DRAM      │ packet 256B 가 PA 0xABCD_0000 에 land        │ (DMA complete)  │ —
   280   │ VF₀ HW         │ ⑦ MSI-X 송신 (VF 별 vector)                  │ MWr 1 DW (MSI-X)│ 00 또는 10
   320   │ VM₀ driver     │ guest interrupt 수신 → packet 처리            │ —               │ —

단계별 의미

Step 누가 무엇을
VF₀ HW ATS Translation Request TLP 송신 (AT=01) ATC miss → IOMMU 에 번역 요청
IOMMU (BDF, PASID, IOVA) → host PA 변환 (page walk) PASID 가 guest VM 의 page table 선택
RC TR Completion (PA + 권한 bit) 응답 ATS 의 핵심 결과
VF₀ ATC (IOVA → PA) 항목 cache 이후 같은 IOVA 는 walk 면제
VF₀ HW MWr (AT=10, Translated) 로 PA 직접 사용 IOMMU 가 다시 walk 안 함
RC + IOMMU AT=10 이면 검증만 (또는 ACS 정책) "이미 번역됐다" 신뢰
VF₀ HW MSI-X 로 guest IRQ VF 별 vector, IOMMU 가 interrupt remap
// VF 의 ATS Cap (Extended Cap ID 0x000F) 활성화 — host hypervisor 가 호출
void enable_ats(uint16_t bdf_vf) {
    uint16_t ats_off = find_ext_cap(bdf_vf, 0x000F);
    if (!ats_off) return; // ATS 미지원
    uint16_t ctrl = cfg_read16(bdf_vf, ats_off + 0x06);
    ctrl |= (1 << 15); // ATS Enable bit
    ctrl |= (32 & 0x1F); // Smallest Translation Unit (STU) hint
    cfg_write16(bdf_vf, ats_off + 0x06, ctrl);
}

// ATC Invalidate 처리 (host → device) — page 가 unmap 될 때
void ats_invalidate(uint16_t bdf_vf, uint64_t iova, uint32_t len) {
    // RC 가 ATS Invalidate Request TLP 송신, device 가 ATC entry drop
    // device 응답으로 ATS Invalidate Completion (모든 inflight 처리 후)
    // 이때 device 는 해당 IOVA 의 in-flight DMA 가 완료 또는 abort 됐음을 보장
}

여기서 잡아야 할 두 가지

(1) AT field 가 TLP 의 행동 규약을 바꾼다 — 같은 MRd/MWr 라도 AT=00 (Untranslated) 면 IOMMU 가 매번 walk, AT=10 (Translated) 면 IOMMU bypass. ATS 의 본질은 device 가 이미 번역했음을 RC 에게 알려주는 신호 이고, RC 는 그 신호를 믿어주는 대신 ACS 로 검증 합니다.
(2) Invalidate 는 in-flight DMA 와 race 가 핵심OS 가 page 를 unmap 할 때 device 의 ATC 만 비우면 끝나는 게 아니라, 그 IOVA 를 사용 중인 in-flight TLP 가 모두 끝날 때까지 Invalidate Completion 을 보내면 안 됨. 그래서 ATS 검증의 가장 어려운 corner case 는 Invalidate-during-DMA. RDMA 의 ODP (Module 05 of RDMA) 와 같은 원리.


4. 일반화 — 가상화 3 축 (SR-IOV, ATS, P2P) 와 CXL 의 위치

4.1 가상화의 3 축

무엇을 해결 TLP 어휘
SR-IOV 한 device 의 function 복제VM 직접 패스스루 PF/VF BDF, derived BAR
ATS IOMMU walk 의 latency AT field, TR Req/Cpl, Invalidate
P2P + ACS RC 우회 path 의 허용 / 보안 ACS Cap, P2P Redirect
(보조) PASID process 분리 (한 VF 안에서 여러 user) PASID prefix

4.2 SR-IOV 구조

                   Host Memory
                       │ DMA
         ┌─────────────┴─────────────┐
         │       PCIe Device          │
         │                            │
         │   ┌──────┐  Physical Func  │ → BDF (B,D,0)
         │   │  PF  │  - 전체 device  │ → host hypervisor 가 사용
         │   │      │  - VF 생성/관리│
         │   └──────┘                  │
         │                            │
         │   ┌──────┐ ┌──────┐ ┌──────┐│
         │   │ VF 0 │ │ VF 1 │ │ VF N ││ → BDF (B,D,1), (B,D,2), …
         │   │      │ │      │ │      ││
         │   └──────┘ └──────┘ └──────┘│
         │   ↑ 각자 별도 BAR + Doorbell │
         │                            │
         └────────────────────────────┘

         VM₁ ── ATS+IOMMU ── VF 0     ← Hypervisor 가 VF 0 을 VM₁ 에 패스스루
         VM₂ ── ATS+IOMMU ── VF 1

4.3 ATS / PRI 의 두 경로

   Normal path (ATC hit) :
   Device ──MWr(AT=10, PA)──▶ RC ──▶ DRAM

   ATC miss path :
   Device ──TR Req(AT=01, IOVA)─▶ RC+IOMMU
            ◀─TR Cpl(PA)─────────  RC+IOMMU
   Device ──MWr(AT=10, PA)──▶ RC ──▶ DRAM

   Page fault path (PRI) :
   Device ──TR Req(AT=01, IOVA)─▶ RC+IOMMU
            ◀─TR Cpl(N=1, no PA)── RC+IOMMU   ← 매핑 없음 통보
   Device ──PRI Page Request────▶ OS via interrupt
            ◀─PRI Page Response── OS가 page-in 후 응답
   Device ──TR Req 재시도────────▶ ...

4.4 P2P 의 정책 결정자 = ACS

                  RC
        ┌────── Switch ──────┐    ← Switch 의 port 가 ACS bit 으로 정책 결정
        │                    │
       EP1 ◀── P2P DMA ───▶ EP2

→ 같은 switch 아래 두 EP 가 P2P 가능 여부는 switch 의 ACS 가 결정. RC 의 ACS 도 별도 영향 (P2P Request Redirect).

4.5 CXL — PCIe 와의 관계

   같은 connector + 같은 PHY
   ┌────────────────────┐
   │ Alternate Protocol │   ← 협상 단계 (LTSSM 초기) 에서 결정
   └────────────────────┘
   ┌────────┴──────────┐
   │                    │
 PCIe path          CXL path
 (Module 01~07)     ├─ CXL.io  : PCIe 호환 (Configuration, MMIO, DMA)
                    ├─ CXL.cache: device → host cache 일관성 참여
                    └─ CXL.mem  : host → device-attached memory

→ CXL 은 PCIe새 버전 이 아니라 대안 프로토콜. 같은 cable, 다른 transport.


5. 디테일 — SR-IOV Cap, ATS TLP, ACS, CXL protocol stack

5.1 SR-IOV 핵심 특징

  • PF (Physical Function): 전체 device 의 entry point, 일반적인 PCIe device 처럼 동작 + VF 생성/제거 권한.
  • VF (Virtual Function): lightweight, 자기만의 BDF + BAR + MSI-X. Configuration register 일부만 지원.
  • VF 의 Configuration SpacePFSR-IOV Capability 에서 derived (VF BAR0 = PF SR-IOV BAR0 + VF index × stride).
  • IOMMUVF 별 PASID 분리 → 게스트가 자기 메모리만 DMA 가능.

사용 예: SR-IOV NIC

   호스트 → NIC PF → 트래픽 분류 (MAC/VLAN) → VF 0 / VF 1 / VF 2 RX queue
   각 VF 는 게스트 VM 에 패스스루 → VM 이 HW 레벨로 RX/TX
   → 가상화 overhead 거의 0, line rate 달성 가능

SR-IOV Capability (Extended Cap ID 0x0010)

   SR-IOV Cap Header
   Initial VFs        : 가능한 VF 갯수
   TotalVFs           : 현재 enable 한 VF 갯수
   NumVFs             : SW 가 활성화한 VF 갯수
   VF Stride          : VF 간 BDF 간격
   First VF Offset    : 첫 VF 의 PF 로부터 BDF offset
   VF Device ID       : VF 의 Device ID (PF 와 다름)
   VF BAR0..5         : VF 의 BAR (size 만 — base 는 enumeration 시 할당)

ARI (Module 06) 가 enable 되어야 256 개 VF 를 지원 (Function # 8-bit 확장).

SR-IOV 가 등장한 배경 — 가상화의 hypervisor overhead

상황: 100 Gbps NIC 1 장 + VM 100 대.

SR-IOV 이전 (Full Emulation):

  • VM 의 게스트 OS 는 옛날 NIC (예: Intel e1000) 인 척 속는 emulated device 와 통신.
  • VM driver 가 가짜 register 에 access 할 때마다 CPUTrap (VM-Exit) → Hypervisor 로 제어 넘어감 → Hypervisor 가 명령 해석 후 실제 PF driver 로 전달.
  • packet 1 개 송신에 trap 수십 번 → 극도로 느림.

VirtIO (반가상화):

  • VM 이 자기가 가상이라는 사실을 인정하고 VirtIO driver 사용.
  • VM 과 hypervisor 사이에 Virtqueue (Ring Buffer) 공유 메모리.
  • VM 이 packet 50 개를 ring buffer 에 쌓아두고 trap 1 번 (Hypercall) → batching → 효율 ↑.

SR-IOV (VF):

  • 위 단계를 하드웨어로 해결VF 가 직접 VM 에 패스스루.
  • VM driver 가 VF BAR 에 직접 access → Trap 없음 (IOMMU 가 검증).
  • packet 1 개 송신에 trap 0 번 — line rate 가능.

vDPA (최신):

  • VM 안에서는 표준 VirtIO driver 그대로.
  • 실제 동작은 SmartNIC 같은 하드웨어가 ring buffer 를 직접 read.
  • VirtIO 의 driver 표준화 + SR-IOV 의 성능 결합.
방식 CPU Trap Live Migration 드라이버 표준화
Full Emulation 매우 많음 쉬움 표준
VirtIO 중간 (batching) 쉬움 표준
SR-IOV (VF) 거의 없음 어려움 벤더 종속
vDPA 거의 없음 가능 표준

MFD vs SR-IOV — 헷갈리기 쉬운 두 가상화 개념

둘 다 "한 device 에 여러 function" 이지만 목적 / 생성 방식 / 권한 모두 다름.

비교 MFD (Multi-Function Device) SR-IOV
기능의 종류 이질적 (NIC + Sound 등 서로 다름) 동질적 (NIC 의 복제)
생성 시점 정적 — 공장에서 HW 고정 동적 — 소프트웨어로 실시간 생성/제거
권한 각 Function 이 독립적 설정 권한 PF 만 글로벌 권한, VF 는 데이터 통로만
목적 단가 절감, 공간 절약 가상화 성능 극대화 (hypervisor 우회)
Configuration Space Function 별 full PF full + VF lightweight

핵심 차이: MFD 의 Function 들은 별개의 기능 을 묶은 것 (예: 한 칩에 NIC + audio). SR-IOVVF같은 기능의 복제 (예: NIC 1 개의 100 개 가상 NIC).

5.2 ATSTLP 흐름 상세

   기존 (without ATS):
   Device DMA 할 때마다 IOMMU 가 page table walk
   → 모든 transaction 마다 latency + IOMMU 부하

   With ATS:
   1) Device 가 ATS Translation Request 송신 (IOVA 포함)
   2) IOMMU 가 PA 응답 (TR Completion)
   3) Device 가 (IOVA → PA) 를 자기 ATC (Address Translation Cache) 에 저장
   4) 이후 같은 IOVA 의 DMA 는 device 가 PA 직접 사용
   → IOMMU walk 회피, 매번 cache hit

Translation TLP 흐름

   Device                                       IOMMU / RC
   ──────                                       ──────────
   ATS Translation Request (with IOVA, PASID)  ──▶
                                                 (IOMMU walk)
                                            ◀── ATS Translation Completion
                                                 (PA, valid bits)

   Device 가 PA 받음, ATC 갱신
   이후:
   Memory Read/Write (with AT field = "Translated") ──▶
                                                 (IOMMU bypass — 이미 PA)

TLPAT field (3-bit) 가 "Untranslated", "Translation Request", "Translated" 표시.

Invalidate

OS 가 page mapping 변경 시:

   OS / IOMMU                                    Device
   ──────────                                    ──────
   ATS Invalidate Request (IOVA range)         ──▶
                                                 (Device ATC entry 무효화)
                                            ◀── ATS Invalidate Completion

→ TLB consistency 유지.

PRI (Page Request Interface)

ATS 가 처리 안 된 IOVA (page fault) 발생 시:

   Device 가 PRI Page Request 송신 (어느 IOVA 에 어떤 access)
   OS / IOMMU 가 page-in 처리
   PRI Page Response 로 device 에 알림
   Device 가 ATS 재시도

→ ODP (On-Demand Paging) 의 PCIe 측 메커니즘. RDMA 의 ODP 와 같은 원리.

5.3 PASID (Process Address Space ID)

   하나의 device 가 여러 process / VM 의 메모리에 동시 DMA 시:
       PASID 가 어느 address space 인지 식별 (20-bit)

   TLP 의 PASID prefix 또는 PASID extension 으로 전달
   IOMMU 가 (BDF, PASID) 쌍으로 page table 결정

→ Process-aware DMA. SVM (Shared Virtual Memory) 의 기반.

5.4 P2P (Peer-to-Peer) DMA

            ┌── RC ──┐
            │         │
            │         │
       ┌────┴───┐ ┌───┴────┐
       │ Switch │ │  Switch│
       └─┬───┬──┘ └────┬───┘
         │   │         │
       ┌─┴─┐│  ┌──┐    │
       │EP1│ │  │EP2│   │
       └───┘ │  └──┘    │
             ▲           ▲
             └────────── │  P2P: EP1 → EP2 직접 DMA
                          └  RC 거치지 않음

   사용 예: GPU 가 NIC RX buffer 직접 read → RDMA over GPU
            NVMe 의 DMA 가 GPU memory 직접 access

ACS (Access Control Services)

P2P 를 허용/차단하는 정책:

ACS bit 의미
Source Validation TLP 의 Requester ID 가 진짜 그 port 에서 왔는가
Translation Blocking "Translated" AT TLP 의 정책
P2P Request Redirect P2P request 를 RC 로 redirect 강제
P2P Completion Redirect P2P completion 을 RC 로 redirect
Upstream Forwarding Switch port 의 forward 정책

Default 보안 정책은 P2P 차단 (RC 우회 가능 = security risk). 명시적으로 enable 해야 P2P 작동.

사용 시나리오

Workload P2P 효과
GPU + NIC 협업 (RDMA over GPU) NIC RXGPU 메모리 직접 (CPU 우회)
NVMe + GPU (직접 데이터 로드) NVMe → GPU 메모리 직접
Multi-GPU 통신 (NCCL P2P) Switch 통해 GPUGPU

CXL 의 위치

   ┌─────────────────────┐
   │  PCIe PHY (공유)     │ ← 같은 SerDes, 같은 connector
   ├─────────────────────┤
   │  Alternate Protocol │ ← 협상 단계에서 PCIe vs CXL 결정
   ├─────────────────────┤
   │  CXL Link Layer     │  (PCIe DLL 와 다름)
   ├─────────────────────┤
   │  CXL.io / .cache /  │
   │   .mem              │
   └─────────────────────┘

3 Protocol

Protocol 역할
CXL.io PCIe 와 호환 — Configuration, MMIO, DMA. 모든 CXL device 의 baseline
CXL.cache Device 가 host memory 의 cache 일관성 참여 (예: accelerator 가 host CPU cache line 을 공유)
CXL.mem Host CPU 가 device-attached memory 를 자기 메모리처럼 access (예: CXL memory module)

Device Type

Type 사용 protocol
Type 1 .io + .cache Cache-coherent accelerator (without local memory)
Type 2 .io + .cache + .mem Cache-coherent accelerator with attached memory (예: AI accelerator)
Type 3 .io + .mem Memory expansion (DDR5 module on CXL link)

CXL 2.0 / 3.0 / 3.1 핵심 추가

  • CXL 2.0: Switching, Pooling (한 memory pool 을 여러 host 가 share)
  • CXL 3.0: Fabric (multi-host with global memory), 강화된 cache 일관성
  • CXL 3.1: Trusted execution, security 강화

CXL 은 modern AI/cloud 의 메모리 확장 표준. PCIe 검증자도 알아야 함.

5.6 PCIe 와 CXL 의 검증 영역 비교

영역 PCIe CXL
PHY / LTSSM 공통 (CXL 도 같은 LTSSM) + Alternate Protocol Negotiation
Link Layer DLLP, ACK/NAK CXL Link Layer (다른 mechanism)
Transport TLP CXL.io = TLP, .cache/.mem = 별도 flit-based
Coherence (없음) .cache 의 MESI-like 프로토콜
Memory model (host 와 분리) .mem 의 host coherence 통합

5.7 검증 시나리오 — Advanced 영역

SR-IOV

시나리오 목표
PF enable + VF 256 TotalVFs/NumVFs setting, ARI 정상
VF BAR access VFBAR offset 계산 정확
MSI-X table 분리 VFMSI-X vector 가 독립
FLR on VF VF 단독 reset, PF 영향 없음
IOMMU 격리 VM₁ VF 가 VM₂ 메모리 접근 시 차단

ATS

시나리오 목표
Translation Request → Completion TLP 흐름 정상
ATC hit / miss Cache 동작
Invalidate OS 의 invalidate 받으면 entry drop
PRI page fault Page Request → Response → 재시도
Invalidate during in-flight DMA in-flight 완료 보장 후 Cpl

P2P / ACS

시나리오 목표
ACS disabled 시 P2P 동작 EP1→EP2 직접 DMA
ACS Source Validation spoofed BDF 거부
Multi-GPU NCCL Switch level P2P

6. 흔한 오해 와 DV 디버그 체크리스트

흔한 오해

❓ 오해 1 — 'CXL 은 PCIe 의 새 버전이다'

실제: CXL 은 PCIePHY 와 일부 layer 를 공유 하지만 별도 protocol family. 같은 cable + 같은 connector 로 두 모드 (PCIe / CXL) 중 하나로 동작 (alternate protocol). CXL device 는 CXL alt-protocol negotiation 후 CXL.io (= PCIe 호환) + CXL.cache + CXL.mem 을 사용. PCIe Base spec 만으로는 CXL 동작 안 함.
왜 헷갈리는가: 둘이 같은 connector + 같은 PHY 를 쓰고 PCIe 6.0 / CXL 2.0 등 같은 시기 발표.

❓ 오해 2 — 'SR-IOVVF 도 일반 PCI device 처럼 모든 Cap 을 가진다'

실제: VFlightweight — Configuration Space 의 일부 (Type 0 header + 일부 Cap) 만 가지며, BARPFSR-IOV Cap 에서 derived (VF_BAR = PF SR-IOV BAR + VF_index × Stride). VF 가 자기만의 AER Cap 을 독립 으로 가지지 않을 수 있고, PM Cap 도 보통 PF 가 대행. Driver 가 VF 에 일반 device 처럼 모든 Cap 을 기대하면 silent failure.
왜 헷갈리는가: BDF 가 독립이라 완전히 별개 device 처럼 보여서.

❓ 오해 3 — 'ATS 를 enable 하면 모든 DMA 가 자동으로 빨라진다'

실제: ATS 의 효과는 같은 IOVA 의 재사용 빈도 에 의존. 매 DMA 마다 다른 IOVA (예: random scatter-gather) 면 매번 TR Req 발생 → walk + TR latency 가 오히려 추가. ATS 가 의미가 있는 워크로드 = hot working set 이 ATC 크기 안에 들어옴. 게다가 Invalidate 중에는 in-flight DMA 처리 race 가 발생해 오히려 latency tail 이 늘 수 있음.
왜 헷갈리는가: "cache = 빠르다" 단순 매핑.

❓ 오해 4 — 'P2P 는 enable 만 하면 동작한다'

실제: ACS 의 default 는 P2P 를 차단 합니다 (보안 정책 — RC 가 모든 TLP 를 보지 못하면 spoofing 가능). P2P 가 동작하려면 (a) 두 EP 사이의 모든 switch port 의 ACS 가 P2P 허용으로 설정, (b) RC 자체가 P2P 를 capability 로 지원해야 함. 일부 enterprise CPU 의 RC 는 P2P 자체를 지원 안 함 — IO die 가 강제로 redirect.
왜 헷갈리는가: NVIDIA GPU/Mellanox NIC 처럼 이미 BIOS/driver 가 ACS 를 자동 설정해주는 환경에 익숙해져서.

❓ 오해 5 — 'PASID 가 ATS 와 같이 enable 되면 OS 가 자동 처리'

실제: PASID 는 별도 Extended Cap (0x0023) 이고 device 가 명시적으로 지원해야 함. PASID-aware device 를 PASID 미지원 IOMMU 위에 두면 silently failTLP 의 PASID prefix 는 무시되고 모든 DMA 가 같은 page table 로 갑니다. Driver 가 두 Cap 의 presence 를 쌍으로 검증해야 함.
왜 헷갈리는가: ATS 와 PASID 가 보통 같이 enable 되어 한 묶음으로 인식.

DV 디버그 체크리스트 (이 모듈 내용으로 마주칠 첫 실패들)

증상 1차 의심 어디 보나
VF enable 후 lspciVF 가 안 보임 PF SR-IOV Cap 의 NumVFs 미설정 or ARI off setpci -s <PF_BDF> ECAP10.W=... 의 NumVFs 필드, lspci -vvvSR-IOV
VF BAR access 시 0xFFFFFFFF read VF BAR base 가 미할당 PF SR-IOV BAR + VF_index × Stride 계산 후 자원 풀에 alloc 됐는지
VM 안에서 VFRX 0 packet IOMMU 의 (BDF, PASID) → guest IOVA mapping 누락 dmesg \| grep -i iommu, host 의 VFIO/iommu group 설정
ATS Translation Request 가 안 가는 듯 ATC 가 항상 hit (또는 Cap enable bit 0) ATS Cap (0x000F) 의 Enable bit, ATC 의 invalidation 시점
ATC stale data 사용 (CV mismatch) Invalidate Completion 전 reuse OS 의 invalidate-then-unmap 순서, device 의 inflight tracking
P2P MWr 가 RC 까지 올라옴 (Redirect 발생) Switch port 의 ACS P2P Request Redirect set lspci -vvv \| grep -A5 ACSCap, ACSCtl 값
PRI page fault 받은 후 device hang OSPRI Page Response 안 보냄 또는 Response Code 가 fail IOMMUPRI 큐 backlog, dmesgPRI 메시지
CXL device 가 PCIe 모드로만 동작 Alt-protocol negotiation 실패 LTSSM trace 의 Modified TS1/TS2 (CXL flag), board 의 strap 설정
cat /sys/kernel/iommu_groups/* 에 device 들이 한 group 으로 묶임 ACS 비활성화 (또는 미지원) → IOMMU 가 격리 못 함 switch port 의 ACS Cap presence, kernel 의 pci=acs_override 옵션

7. 핵심 정리 (Key Takeaways)

  • SR-IOV = 한 device 의 여러 VF, 각 VF 가 별도 BDF + 게스트 직접 패스스루. PF 가 관리 권한, VF 는 데이터 통로.
  • ATS = device 의 IOVA→PA cache. 재사용 IOVA 만 의미 있음. Invalidate-during-DMA 가 가장 어려운 corner.
  • PASID = process 별 address space, SVM 의 기반. 별도 Cap 으로 device + IOMMU 양쪽 모두 지원해야.
  • P2P + ACS = device ↔ device DMA + 허용 정책. Default 는 차단. GPUNIC, NVMe↔GPU 의 핵심.
  • CXL = PCIe PHY 공유 + 별도 Link Layer + (.io/.cache/.mem). Type 1/2/3 device. PCIe 의 새 버전 아님.

실무 주의점

  • SR-IOV VF 갯수 = silicon resource 의 함수. spec 상 256 까지지만 실제 device 가 4 / 16 / 64 등 제한.
  • ATS Invalidate latency 가 IOMMU 와 device 의 latency 합 — 그동안의 stale TLB 사용 시점 = security/correctness risk.
  • P2P 사용 시 ACS 의 default 차단 정책 모르면 "왜 P2P 안 됨?" hang. 일부 IOMMU/RC 는 P2P 자체를 capability 로 지원 안 함.
  • CXL 은 PCIe 와 같은 connector 라 hot swap 했을 때 PCIe ↔ CXL 협상 다시 발생. 양쪽 모드 모두 검증 필요.
  • PASID 가 enabled 안 된 IOMMU 위에 PASID-aware device 두면 silently fail — driver 가 capability 검증 필수.
  • SR-IOV + ATS + PASID 의 stacked 검증이 가장 어려움 — 각 축의 단독 검증 통과 후 조합 시나리오 가 별도 sign-off.

7.1 자가 점검

🤔 Q1 — ATS Invalidate race (Bloom: Analyze)

IOMMU 가 page unmap → ATS Invalidate 발송. Device 의 ATC (cache) 가 아직 cache 응답 → invalidate 도착 전 DMA 사용. Race?

정답

Spec: ATS Invalidate 의 Completion 받기 IOMMUunmap 완료 보고 못함.

  • IOMMU: unmap 요청 후 ATS Invalidate 전송.
  • 도착할 때까지: device 의 ATC stale TLB 가능.
  • Completion 수신 후: ATC 무효화 확정 → OSpage free 안전.

DV: ATS Invalidate completion latency 측정 → IOMMUunmap 응답 wait SVA.

🤔 Q2 — SR-IOV + ATS + PASID stack (Bloom: Evaluate)

셋 조합. 가장 흔한 silent fail?

정답

PASID capability mismatch: - Device: PASID-aware (예: GPU). - IOMMU: PASID 미지원. - Driver: capability 검증 누락.

결과: device 가 PASID-tagged TLP 보냄 → IOMMUignore → 모든 DMAwrong context.

Driver 가 pci_pasid_features 같은 capability 검증 필수.

7.2 출처

External - PCIe SR-IOV / ATS / PASID specifications - CXL Consortium spec - Linux IOMMU subsystem


다음 모듈

Module 09 — Quick Reference Card: 모든 모듈의 핵심을 한 페이지에 압축. 검증/리뷰 시 보조 자료.

퀴즈 풀어보기 →