--- title: AMD-Vi (IOMMU) Completion-Wait timeout — 부분 hang 메커니즘과 차단 updated: 2026-05-05 tags: [infra, kernel, iommu, amd, freeze, troubleshooting] --- ## 개요 AMD Ryzen 호스트에서 발생하는 IOMMU(AMD-Vi) Completion-Wait timeout으로 인한 호스트 부분 hang 패턴 정본. 처음 만난 사례는 [[2026-05-04-amd-iommu-freeze]] (incus-kr2, Ryzen 9 6900HX). AMD Ryzen 베어메탈을 신규 도입할 때마다 선제 차단(`iommu=pt`)할 것. ## IOMMU(AMD-Vi)가 하는 일 PCIe/USB 디바이스가 메모리에 DMA 할 때 **"디바이스가 보는 주소(IOVA) → 실제 물리 메모리(PA)"** 변환 수행. - 보안: 디바이스가 임의 메모리 접근 못 하게 격리 (e.g. 악성 USB가 RAM 덤프 못 함) - 가상화: VFIO passthrough, SR-IOV에 필수 - AMD에서는 `AMD-Vi`, Intel에서는 `Intel VT-d`라 부름. 동일 개념 ## 정상 동작 ``` 1. OS가 페이지 매핑을 바꿀 때마다 IOMMU에 invalidation 명령 전송 → IOMMU 내부 캐시(IOTLB)를 비우라고 2. 명령은 IOMMU의 Command Queue에 쌓임 3. 끝에 Completion-Wait 명령으로 "여기까지 다 처리됐는지 알려줘" sync 4. OS는 이 응답을 기다림 (1초 내) ``` ## 펌웨어 버그 발현 시 흐름 1. 어떤 조건에서 펌웨어/HW가 Completion-Wait 응답을 못 보냄 2. Linux가 1초 후 타임아웃 → `dmesg`에 `AMD-Vi: Completion-Wait loop timed out` 출력 3. **타임아웃이 나면 큐 상태가 inconsistent해져 다음 invalidation도 같은 큐에서 stuck** 4. 새 IO나 새 매핑이 필요한 모든 작업이 IOMMU 응답 대기로 hang 5. 누적될수록 hang하는 작업 범위가 넓어져 결국 호스트 사용자공간 대부분이 부분 hang ## 부분 hang의 특이 패턴 — "왜 일부만 죽는가" | 영향 받는 작업 | 영향 안 받는 작업 | |---|---| | 새 fork (페이지 매핑) | 이미 메모리에 매핑된 프로세스 (예: nginx, node-exporter) | | 디스크 쓰기 (NVMe DMA 셋업) | ICMP (커널 raw socket, 이미 셋업된 NIC ring buffer) | | 새 컨테이너 시작 | LXC 컨테이너 내부에서 이미 떠 있는 서비스 | | sshd login (utmp/journal 쓰기) | 이미 열려있는 SSH 세션 | | containerd / incus 데몬의 신규 작업 | 라우팅·NAT처럼 커널이 자체 처리하는 트래픽 | → 외부에서 보면 "ICMP 응답 OK, nginx 응답 OK, 그런데 SSH banner 직후 끊기고 K3s NotReady"라는 미스터리한 부분 hang. 동시에 OOM/디스크/NIC가 모두 멀쩡 (메트릭상 정상). [[2026-05-04-amd-iommu-freeze]] 참조. ## 영향 받는 하드웨어 / 트리거 조건 - **AMD Ryzen 6000 시리즈 (Rembrandt, Zen 3+)** — 알려진 펌웨어 이슈, 다수 보고 (Linux 메일링리스트, AMD 포럼) - **AMD Ryzen Mobile / 미니 PC** — BIOS AGESA 업데이트가 늦거나 안 되는 환경에서 더 자주 발현 - 일부 Intel 플랫폼(VT-d)에서도 비슷한 패턴 보고 있으나 본 정본은 AMD 한정 트리거되는 일반 조건: - DMA 자주 쓰는 디바이스 (NVMe, USB 컨트롤러, 10G NIC) 다수 동시 동작 - VFIO/가상화 + LXC/Docker 같은 컨테이너 동시 동작 - 부팅 후 일정 시간 (사례에서는 24분) 후 첫 timeout, 이후 누적 ## 진단 신호 ```bash # 1차 확인 — Completion-Wait timeout 발생 여부 sudo dmesg -T | grep -iE "AMD-Vi.*Completion-Wait|AMD-Vi.*timed out" # 부분 hang 의심 시 부수 증거 ssh 'echo ok' # banner 직후 끊기면 의심 kubectl get nodes # NotReady, container runtime is down node_procs_blocked # 0이어도 안전 신호 아님 (IOMMU hang은 D-state 안 거침) node_memory_* # 정상이어도 안전 신호 아님 ``` **핵심 함정**: `node_procs_blocked = 0`, `MemoryPressure = False`, `DiskPressure = False` 다 정상이어도 hang 가능. IOMMU layer는 OS가 노출하는 압박 메트릭에 안 잡힘. **메트릭 정상 + 외부 ICMP 응답 + 새 SSH 거부 조합이면 IOMMU 의심.** ## 차단 옵션 ### 1. `iommu=pt` (권장 — Passthrough 모드) GRUB cmdline에 추가: ```bash sudo cp /etc/default/grub /etc/default/grub.bak.$(date +%Y%m%d)-iommu sudo sed -i -E 's/^(GRUB_CMDLINE_LINUX_DEFAULT="[^"]*)(")/\1 iommu=pt\2/' /etc/default/grub sudo update-grub sudo systemctl reboot ``` 검증: ```bash cat /proc/cmdline | grep iommu=pt sudo dmesg | grep "iommu: Default domain type" # 기대: "iommu: Default domain type: Passthrough (set via kernel command line)" ``` **왜 해결되는가**: `pt` 모드는 **호스트 자신의 DMA에 대해 IOMMU 변환을 1:1 mapping으로 고정** → invalidation 거의 안 씀 → Completion-Wait 자체가 발생하지 않음 → 펌웨어 버그 트리거 안 됨. VFIO/SR-IOV 가상화는 여전히 IOMMU 사용 가능 (격리 유지). 트레이드오프는 호스트 자체 DMA 격리가 약해지는 것 — 베어메탈 + 알려진 디바이스 환경에서는 보통 수용 가능한 비용. ### 2. `amd_iommu=off` (차선) IOMMU 자체를 비활성. VFIO passthrough 못 함, SEV/Confidential Computing 못 함. 가상화 안 쓰는 호스트면 가능하나 기본 권장 X. ### 3. BIOS AGESA 업데이트 (장기 대책) 펌웨어 fix가 들어간 AGESA 마이크로코드로 업데이트. Mini PC 제조사가 BIOS를 늦게 내거나 안 내면 불가능. 가능할 때 적용. ### 4. 커널 업그레이드 Linux 6.13+에서 일부 우회 패치 머지된 사례 있음. 효과는 트리거 조건에 따라 다름. `iommu=pt`로 먼저 차단하고 부수적으로 검토. ## 운영 규칙 (kappa 인프라) 1. **AMD Ryzen 베어메탈 신규 도입 시 처음부터 GRUB cmdline에 `iommu=pt` 박을 것.** 사고 경험한 다음 적용은 늦음 — 첫 freeze까지 평균 2주 간격. 2. 호스트 문서(`infra/compute/hosts/.md`)의 GRUB 섹션에 `iommu=pt` 표시. 3. 기존 호스트 점검: `ssh 'cat /proc/cmdline'` 해서 `iommu=pt` 없으면 다음 정기 재부팅 시 추가. 4. 시간대 `Asia/Seoul` 강제. 잘못된 timezone(예: PDT)은 dmesg 분석 시 시간 변환 오류로 잘못된 결론 유도 ([[2026-05-04-amd-iommu-freeze]] 헤임달 1차 진단 오판 사례). 5. AMD Ryzen 호스트는 OOB 전원 제어(Tapo 또는 IPMI) 필수. 펌웨어 hang은 OS shutdown으로 못 풀고 강제 전원 차단만 가능. ## 현재 적용 호스트 상태 | 호스트 | CPU | iommu=pt | 비고 | |---|---|---|---| | [[incus-kr2]] | AMD Ryzen 9 6900HX | ✓ (2026-05-04) | 본 사건 진원지 | | [[incus-kr1]] | unknown | — | 점검 필요 | | [[incus-hp1]] | Intel Xeon E5-2670 | N/A | Intel, AMD-Vi 무관 | | [[incus-hp2]] | Intel Xeon E5-2670 | N/A | Intel, AMD-Vi 무관 | ## 참조 - [[2026-05-04-amd-iommu-freeze]] — 진단 + 조치 사연 - [[infra-hosts]] — 인프라 호스트 정본 - Linux kernel: `drivers/iommu/amd/iommu.c` — `__domain_flush_pages`, `iommu_completion_wait` - AMD I/O Virtualization Technology Specification (IOMMU)