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 문서에 링크
This commit is contained in:
@@ -84,6 +84,7 @@ ro usbcore.autosuspend=-1 quiet iommu=pt
|
|||||||
|
|
||||||
## 관련 문서
|
## 관련 문서
|
||||||
|
|
||||||
|
- [[amd-vi-iommu]] — AMD-Vi 부분 hang 메커니즘 정본 (왜 일부 프로세스만 죽는가, `iommu=pt`가 왜 해결하는가)
|
||||||
- [[infra/compute/hosts/incus-kr2|incus-kr2]]
|
- [[infra/compute/hosts/incus-kr2|incus-kr2]]
|
||||||
- [[2026-04-04-usb-25g-hang]] — 직전 freeze (USB)
|
- [[2026-04-04-usb-25g-hang]] — 직전 freeze (USB)
|
||||||
- [[infra/compute/infra-hosts]]
|
- [[infra/compute/infra-hosts]]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: compute 인덱스
|
title: compute 인덱스
|
||||||
updated: 2026-04-16
|
updated: 2026-05-05
|
||||||
tags: [moc, compute]
|
tags: [moc, compute]
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -9,5 +9,6 @@ tags: [moc, compute]
|
|||||||
| 문서 | 설명 |
|
| 문서 | 설명 |
|
||||||
|------|------|
|
|------|------|
|
||||||
| [[infra-hosts]] | 인프라 호스트 및 네트워크 (SSH 접속, Incus, Tailscale) |
|
| [[infra-hosts]] | 인프라 호스트 및 네트워크 (SSH 접속, Incus, Tailscale) |
|
||||||
|
| [[amd-vi-iommu]] | AMD-Vi (IOMMU) Completion-Wait timeout 부분 hang 메커니즘과 차단 (`iommu=pt`) |
|
||||||
| [[k3s-migration]] | K3s PostgreSQL 백엔드 이전 기록 |
|
| [[k3s-migration]] | K3s PostgreSQL 백엔드 이전 기록 |
|
||||||
| [[zlambda]] | zlambda Linode 도쿄 NixOS VM |
|
| [[zlambda]] | zlambda Linode 도쿄 NixOS VM |
|
||||||
|
|||||||
132
infra/compute/amd-vi-iommu.md
Normal file
132
infra/compute/amd-vi-iommu.md
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
---
|
||||||
|
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 <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에 추가:
|
||||||
|
|
||||||
|
```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/<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)
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: incus-kr2
|
title: incus-kr2
|
||||||
updated: 2026-05-04
|
updated: 2026-05-05
|
||||||
tags: [infra, host, incus, k3s, seoul, amd, iommu]
|
tags: [infra, host, incus, k3s, seoul, amd, iommu]
|
||||||
type: host
|
type: host
|
||||||
host_kind: server
|
host_kind: server
|
||||||
@@ -39,17 +39,9 @@ Incus + K3s control-plane 호스트 (서울존). Mini PC 폼팩터, AMD Ryzen 9
|
|||||||
|
|
||||||
## 알려진 hang 패턴 — AMD-Vi (IOMMU) Completion-Wait Timeout
|
## 알려진 hang 패턴 — AMD-Vi (IOMMU) Completion-Wait Timeout
|
||||||
|
|
||||||
호스트 freeze가 반복 발생한 근본 원인 (2026-05-04 확정, [[2026-05-04-amd-iommu-freeze]]).
|
호스트 freeze 반복의 근본 원인. 메커니즘 정본은 [[amd-vi-iommu]], 사건 사연은 [[2026-05-04-amd-iommu-freeze]].
|
||||||
|
|
||||||
**증상**:
|
요약: AMD Ryzen 6900HX IOMMU의 Completion-Wait queue가 stall되면서 DMA 의존 디바이스(NVMe, USB 컨트롤러 등)가 멈춤 → containerd/incus/sshd login만 죽고 ICMP/이미 매핑된 프로세스(nginx, node-exporter)는 살아남는 부분 hang. 조치: GRUB cmdline `iommu=pt` 추가 (2026-05-04 적용, 17시간 timeout 0건 검증).
|
||||||
- ICMP/이미 매핑된 프로세스(node-exporter, LXC 컨테이너 nginx)는 응답 유지
|
|
||||||
- containerd, incus 데몬, sshd 새 세션 fork만 동시에 hang
|
|
||||||
- kubelet `container runtime is down`, `/var/log/pods readdirent: input/output error`
|
|
||||||
- procs_blocked 0, MemoryPressure False — 자원 고갈 아님
|
|
||||||
|
|
||||||
**원인**: AMD Ryzen 6900HX IOMMU(AMD-Vi) Completion-Wait queue stall. `dmesg`에 `AMD-Vi: Completion-Wait loop timed out` 반복 후 누적되어 DMA 의존 디바이스(NVMe, USB 컨트롤러 등)가 stall.
|
|
||||||
|
|
||||||
**조치 (2026-05-04 적용)**: GRUB cmdline `iommu=pt` 추가 → IOMMU passthrough 모드. dmesg `iommu: Default domain type: Passthrough` 확인.
|
|
||||||
|
|
||||||
**과거 freeze 이력 비교**:
|
**과거 freeze 이력 비교**:
|
||||||
| 일자 | 원인 | 조치 |
|
| 일자 | 원인 | 조치 |
|
||||||
|
|||||||
Reference in New Issue
Block a user