Files
obsidian/infra/compute/amd-vi-iommu.md
kaffa 0a45e0536c AMD-Vi (IOMMU) Completion-Wait timeout 메커니즘 정본 신설
incus-kr2 freeze 사건 분석으로 확정된 IOMMU 부분 hang 메커니즘과
운영 규칙(`iommu=pt` 선제 적용)을 별도 reference 문서로 분리.
호스트 사연(history)과 메커니즘(reference)을 분리해 다른 AMD Ryzen
호스트 도입 시 재사용 가능한 정본으로 정리.

- infra/compute/amd-vi-iommu.md 신규 (메커니즘 + 차단 + 운영 규칙)
- compute _index.md, hosts/incus-kr2.md, history 문서에 링크
2026-05-05 11:47:31 +09:00

6.8 KiB

title, updated, tags
title updated tags
AMD-Vi (IOMMU) Completion-Wait timeout — 부분 hang 메커니즘과 차단 2026-05-05
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초 후 타임아웃 → dmesgAMD-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, 이후 누적

진단 신호

# 1차 확인 — Completion-Wait timeout 발생 여부
sudo dmesg -T | grep -iE "AMD-Vi.*Completion-Wait|AMD-Vi.*timed out"

# 부분 hang 의심 시 부수 증거
ssh <host> '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에 추가:

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

검증:

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/<name>.md)의 GRUB 섹션에 iommu=pt 표시.
  3. 기존 호스트 점검: ssh <host> '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)