virtio-nvgpu는 KVM 가상 머신에서 거의 본래 수준의 NVIDIA GPU 성능을 가능하게 합니다
KVM 가상 머신 내부의 거의 본래 수준의 NVIDIA GPU 접근
핵심 요약: virtio-nvgpu는 호스트와 가상 머신 간에 NVIDIA 커널 드라이버의 ioctls를 드라이버 ABI 수준에서 전달하여, Linux KVM 가상 머신이 수정되지 않은 NVIDIA 사용자 모드 드라이버를 실행하고, 본래 시스템과 비교해 2% 내외의 렌더링 성능을 달성하며, 거의 추가적인 CPU 비용 없이 가능하게 합니다.
작동 방식
- **가상 머신 커널 드라이버 (GPL)**는 일반적인
/dev/nvidia*노드를 등록합니다. 각ioctl()호출 시 원시 요청을 virtqueue에 직렬화하고,mmap()시에는 공유 메모리 창을 가상 머신 프로세스에 직접 매핑합니다. - **장치 크레이트 (Apache-2.0, Rust)**는 VMM 내에서 실행되며, 이러한 virtqueue 메시지를 수신하고 내장된 파일 디스크립터와 포인터를 변환한 후, 호스트의 NVIDIA 드라이버로 ioctl을 전달합니다. 버퍼 관리는 여기에 있습니다.
- 이벤트 virtqueue는 GPU가 작업을 완료했을 때 가상 머신에 알립니다. 이로 인해 바쁜 폴링이 제거됩니다.
- 격리 계획 – 미래의 각 가상 머신용 사전 격리된 보조 프로세스(isolate 컴포넌트)가 실제 장치 파일 디스크립터를 보유할 예정입니다. 현재는 VMM 프로세스가 직접 이를 보유하고 있습니다.
이 아키텍처는 chromeos/virtio-media를 모방합니다: GPL 라이선스의 가상 머신 드라이버와 허용성 라이선스를 가진, VMM에 종속되지 않는 장치 크레이트가 함께 있으며, 모든 VMM 상호작용은 트레이트로 표현됩니다.
성능 결과 (RTX 3060, 드라이버 595.99.02)
| 메트릭 | 가상 머신 (virtio-nvgpu) | 본래 시스템 호스트 |
|---|---|---|
| 일반 게임 렌더링 프레임 시간 (≥2 ms) | -0.4% ~ +1.7% (노이즈 수준 내) | — |
| 초경량 렌더링 프레임 시간 (≤0.5 ms) | 최대 +40.8% (대기 비용이 주요 원인) | — |
| 100fps 비패스 실행 시 CPU 사용량 (12초) | 0.37초 | 0.40초 |
| 프레임당 호스트-가상 머신 전환 횟수 | ≈0.02 (약 59프레임당 1회) | 수천 회 (Venus) |
| 다중 가상 머신 스케일링 (RTX 3060에 4개 가상 머신) | 총 103.7fps, 각각 약 25.8fps, 싱글 가상 머신 성능과 동일 | — |
해석: GPU 기반 작업 부하에 대해 가상 머신은 본래 시스템과 구분할 수 없으며, 프레임 예산이 GPU 깨우기 지연 시간(~0.02ms)보다 작은 경우에만 측정 가능한 손실이 나타납니다.
지원되는 사용 사례
- Vulkan 및 OpenGL 렌더링 (헤드리스 EGL도 작동함)
- 가상 머신 내부의 Wayland 컴포지터, 오프스크린 프레임 출력
- CUDA 메모리 할당 및 Vulkan/GL과의 제로-코피 상호운용성
- 가상 머신 측 CUDA 버퍼에서 직접 NVENC 인코딩 (H.264/H.265 출력)
이 설계는 물리적 스캔아웃, MIG/SR-IOV, 그리고 완전한 통합 가상 메모리(cudaMallocManaged)를 의도적으로 제외합니다.
드라이버 ABI 처리
NVIDIA의 커널 드라이버 ABI는 릴리스 간에 변경됩니다. virtio-nvgpu는 명시적인 ABI 프로파일을 제공합니다:
| 프로파일 | 적용 범위 |
|---|---|
535.129.03 |
535.129.03부터 다음 프로파일까지 |
580.178.04 |
580.178.04부터 다음 프로파일까지 |
595.71.05 |
595.71.05 및 이후 버전 |
535.129.03보다 오래된 드라이버는 거부됩니다. 더 새로운 드라이버는 마지막 프로파일에 따라 수용되며, 새로운 프로파일이 추가될 때까지 유지됩니다. 프로파일은 NVIDIA의 open-gpu-kernel-modules 소스에서 기계적으로 생성되며, 수동으로 입력된 것이 아닙니다.
다른 GPU 가상화 접근 방식과의 비교
| 접근 방식 | 가상 머신 드라이버 | API 번역 | GPU 공유 | NVENC 지원 | 격리 수준 |
|---|---|---|---|---|---|
| VFIO 패스스루 | 호스트 드라이버가 가상 머신 PCI 장치에 바인딩됨 | 없음 (네이티브) | GPU당 하나의 VM (또는 전용 카드) | 네이티브로 작동 | 강함 (IOMMU가 가상 머신 메모리를 격리함) |
| virtio-gpu + Venus | 가상 머신 Mesa 드라이버 (virgl) | 프레임당 단일 호출 직렬화 및 재생 | 여러 VM이 GPU 공유 | 불가능 (버퍼가 호스트에 존재함) | 중간 |
| virtio-nvgpu (이 프로젝트) | 수정되지 않은 NVIDIA 사용자 모드 드라이버 | 드라이버 ABI 수준에서 ioctl 전달 (약 프레임당 1회 전환) | 여러 VM이 단일 카드 공유 (최대 4개까지 테스트됨) | 작동, 제로-코피 | 약함 – 모든 ioctl이 전달됨; 호스트 드라이버는 TCB에 있음 |
핵심 통찰: 그래픽 API가 아닌 커널 드라이버 수준에서 번역 경계를 이동함으로써,
virtio-nvgpu는 Venus의 막대한 프레임당 호출 오버헤드를 제거하면서도 여러 가상 머신이 GPU를 공유할 수 있게 합니다.
보안 및 격리 고려 사항
- 가상 머신 GPU 작업과 호스트 메모리 사이에 IOMMU 경계가 없음. 호스트 NVIDIA 드라이버는 호스트의 IOMMU 도메인에서 실행되며, 신뢰할 수 있는 컴퓨팅 기반(TCB)의 일부로 간주됨.
- 현재 구현은 모든 드라이버 ioctl을 전달하지만, ABI 프로파일에서 명시적으로 거부된 것만 제외함. 디버깅을 위해 더 관대한 플래그(
--permissive-abi)를 사용할 수 있음. - 미래 작업(
isolate/)은 각 가상 머신용 격리된 보조 프로세스에 실제 장치 파일 디스크립터를 격리하려는 것이지만, 아직 구현되지 않음. - VFIO와 비교했을 때 공격 표면은 더 큼: 해킹된 가상 머신은 허용된 모든 ioctl을 실행할 수 있으며, 호스트에서 GPU를 공유하는 여러 프로세스를 실행하는 것과 유사함.
커뮤니티 피드백 (Hacker News 요약)
- @refibrillator는 GPU 공유의 세 가지 주요 방법(VFIO, virtio-gpu/Venus, virtio-nvgpu)을 언급하고,
virtio-nvgpu가 호스트 드라이버가 TCB에 있기 때문에 가장 약한 격리 수준을 제공한다고 지적함. - @orphereus는 왜 일반 GPU 패스스루를 사용하지 않는지 묻고, 답은 패스스루로 VM 간 GPU 공유가 불가능하다는 것임.
- @markasoftware는 이 것이 gVisor의
nvproxy와 어떻게 다른지 묻고, README는nvproxy를 직접적인 영감으로 언급하지만 차이점은 상세히 설명하지 않음. - @ericd는 VFIO 복잡성 없이 성능이 뛰어난 게임용 가상 머신에 대해 기대감을 표현함.
- @majorchord는 Windows 가상 머신 지원 여부를 묻고, 현재 프로젝트는 Linux 가상 머신만 대상으로 함.
저장소 구조
| 디렉터리 | 라이선스 | 목적 |
|---|---|---|
driver/ |
GPL-2.0 | virtqueue를 통해 ioctl과 mmap을 전달하는 가상 머신 커널 모듈 |
device/ |
Apache-2.0 | VMM에 종속되지 않는 Rust 크레이트로 virtio 장치 및 ABI 번역 구현 |
isolate/ |
Apache-2.0 | 미래의 각 가상 머신용 격리된 보조 프로세스 설계 노트 (코드 없음) |
gen/ |
— | NVIDIA 소스에서 기계적으로 생성된 ABI 테이블 |
protocol/ |
BSD-3-Clause OR GPL-2.0+ | 공유된 와이어 형식 및 ABI 정의 |
시작하기
- 가상 머신 드라이버(
driver/)를 빌드하고 KVM 가상 머신 내부에 로드합니다. - 필요한 트레이트(디스크립터 체인 I/O, 이벤트 처리, 가상 머신/호스트 메모리 매핑)를 구현하여
device/크레이트를 VMM에 통합합니다. - 가상 머신 내부에서 Vulkan 또는 Wayland 애플리케이션을 실행합니다. README의 벤치마크 스크립트(
BENCHMARKS.md)를 통해 거의 본래 수준의 성능을 검증할 수 있습니다.
제한 사항 및 미래 작업
- 단일 RTX 3060에 최대 4개의 가상 머신에서 테스트됨; 더 많은 가상 머신은 테스트되지 않음.
- 테스트된 드라이버 버전은 595.99.02 (RTX 3060)과 615.71.09 (RTX A2000)뿐이며, 다른 카드는 테스트되지 않음.
- CUDA 기능은 전달되지만, 열거 외에는 철저히 검증되지 않음.
- Windows 가상 머신 지원은 아직 없음. 프로젝트는 Linux만 대상으로 함.
- 격리 개선(각 가상 머신용 사전 격리, seccomp 필터)은 계획되어 있으나 현재는 없음.
라이선스
저장소는 세 가지 라이선스 영역을 포함합니다: 가상 머신 드라이버는 GPL-2.0, 장치 크레이트와 isolate 설계는 Apache-2.0, 공유 프로토콜 헤더는 BSD-3-Clause (또는 GPL-2.0+)입니다.
결론적으로, virtio-nvgpu는 NVIDIA 드라이버 ioctl을 ABI 수준에서 전달함으로써, KVM 가상 머신이 거의 본래 수준의 GPU 성능을 달성하면서도 단일 카드를 여러 VM이 공유할 수 있음을 보여줍니다. 다만, VFIO 패스스루보다는 격리 수준이 약합니다.