快轉到主要內容

解鎖Arch Linux的Nvidia vGPU虛擬化,增強QEMU/KVM虛擬機圖形效能

分類   資訊科技 虛擬機與容器技術
標籤   GPU Virtualization Nvidia Arch Linux
🗓️ 民國113年 甲辰年
✍ 切換正體/簡體字
目錄

現在我有Intel內顯 + Nvidia獨顯的電腦,如果要增強QEMU/KVM虛擬機圖形效能,我們會使用Nvidia GPU Passthrough的方式讓虛擬機使用顯示卡資源,再讓Intel內顯負責顯示畫面。

相關文章: Arch Linux如何將Nvidia GPU直通給Windows QEMU/KVM虛擬機

本文探討另一個作法:GPU虛擬化,透過Nvidia的vGPU技術,動態分配Nvidia顯示卡給QEMU/KVM虛擬機使用。

下圖是Nvidia官網的架構圖,與GPU Passthrough比起來,vGPU可以一對多,將顯示卡資源切分給多個虛擬機使用。且不需要把Nvidia顯示卡驅動加入開機黑名單,也不需要綁定VFIO裝置。

我目前的用法是在BIOS調整,由Intel內顯當作Linux電腦的主顯示卡,Nvidia顯示卡在旁納涼,這樣才不會因為意外操作而沒畫面。

vGPU啟用有點複雜,Nvidia不會讓一般人用vGPU的,你需要安裝給企業使用的專門驅動程式。且如果顯示卡不支援vGPU功能,你還得手動打patch。

支援vGPU的顯示卡列表請看 官方列表,Quadro可以直接用,我的是GeForce系列需要手動打patch。

vgpu unlock支援的GPU
#

根據 這篇issue,目前vgpu unlock僅支援MX300、GTX1000、GTX1600及RTX2000系列,不支援RTX3000以上的GPU。

1. 環境
#

  • Host OS:Arch Linux
  • Guest OS:Windows 11 23H2
  • 核心版本:6.6.11
  • QEMU版本:8.2.0
  • Libvirt版本:9.10.0
  • CPU:Intel i5-7400
  • GPU:Intel UHD 630
  • GPU:Nvidia GeForce GTX 1050 Ti
  • Nvidia驅動版本:535.129.03

2. 啟用IOMMU和VFIO
#

如果你有直通過GPU,請將之前做的步驟全撤銷。

  1. 編輯GRUB
sudo vim /etc/default/grub
  1. 啟用Intel的IOMMU功能
GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 quiet intel_iommu=on iommu=pt"
  1. 編輯mkinitcpio.conf
sudo vim /etc/mkinitcpio.conf
  1. 設定開機載入vfio核心模組
MODULES=(vfio_pci vfio vfio_iommu_type1)
  1. 更新initramfs和GRUB,重開機
sudo mkinitcpio -p linux
sudo grub-mkconfig -o /boot/grub/grub.cfg
sudo reboot

3. 設定vGPU系統服務
#

vgpu_unlock-rs專案可以在系統跑一個解鎖vGPU功能的系統服務。

  1. 安裝編譯套件
sudo pacman -S git base-devel dkms linux-headers rust

yay -S mdevctl
  1. 用cargo編譯vgpu_unlock
su
cd /opt
git clone https://github.com/mbilker/vgpu_unlock-rs.git
cd vgpu_unlock-rs/
cargo build --release
  1. 編譯後啟動vgpu_unlock系統服務
mkdir /etc/vgpu_unlock
touch /etc/vgpu_unlock/profile_override.toml

mkdir /etc/systemd/system/{nvidia-vgpud.service.d,nvidia-vgpu-mgr.service.d}
echo -e "[Service]\nEnvironment=LD_PRELOAD=/opt/vgpu_unlock-rs/target/release/libvgpu_unlock_rs.so" > /etc/systemd/system/nvidia-vgpud.service.d/vgpu_unlock.conf
echo -e "[Service]\nEnvironment=LD_PRELOAD=/opt/vgpu_unlock-rs/target/release/libvgpu_unlock_rs.so" > /etc/systemd/system/nvidia-vgpu-mgr.service.d/vgpu_unlock.conf

4. 給顯示卡驅動打patch
#

這裡使用Nvidia官方run版本的驅動,應適用於大多數Linux發行版。

  1. 解除安裝目前的驅動程式,重開機
sudo pacman -R nvidia-dkms
  1. 啟用vGPU需要特製版的Nvidia Grid Driver,到 Nvidia官網註冊企業帳號才能下載Nvidia vgpu-kvm driver。不然你直接Goole搜尋nvidia-linux-x86_64-535.129.03-vgpu-kvm.run也能找到熱心網友提供的檔案,但風險自負就是。

  2. 我的是GeForce系列顯示卡,需要手動給.run檔案打patch。下載vgpu-proxmox專案提供的檔案,套用patch。

chmod +x nvidia-linux-x86_64-535.129.03-vgpu-kvm.run

git clone https://gitlab.com/polloloco/vgpu-proxmox.git

./NVIDIA-Linux-x86_64-535.129.03-vgpu-kvm.run --apply-patch vgpu-proxmox/535.129.03.patch
  1. 之後會得到NVIDIA-Linux-x86_64-535.129.03-vgpu-kvm-custom.run檔案,接著以DKMS模式安裝驅動
sudo ./NVIDIA-Linux-x86_64-535.129.03-vgpu-kvm-custom.run --dkms
  1. 更新initramfs
 sudo mkinitcpio -p linux
  1. 重開機,檢查Nvidia驅動狀況
nvidia-smi
  1. 檢查vgpu是否啟用
nvidia-smi vgpu

5. 建立vGPU mdev裝置
#

註:這一段我無法成功,卡在最後一段賦予UUID的部份,一直遇到「不適用的引數」錯誤。可能是Arch Linux核心太新了?換Ubuntu LTS比較好。

  1. 取得顯示卡PCI位址
lspci | grep NVIDIA
  1. 取得GPU在Virsh中的full identifier,例如這裡是pci_0000_01_00_0
virsh nodedev-list --cap pci| grep 01_00_0
  1. 取得domain, bus, slot, function資訊
virsh nodedev-dumpxml pci_0000_01_00_0 | egrep 'domain|bus|slot|function'

範例輸出:

<domain>0</domain>
    <bus>1</bus>
    <slot>0</slot>
    <function>0</function>
      <address domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
      <address domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
      <address domain='0x0000' bus='0x01' slot='0x00' function='0x1'/>
  1. 列出可用設定檔(也可以用mdevctl types指令查看)
ls -l /sys/bus/pci/devices/0000:01:00.0

ls /sys/class/mdev_bus/0000:01:00.0/mdev_supported_types
  1. 賦予uuid
uuidgen
echo "填入UUID" > /sys/class/mdev_bus/0000:01:00.0/mdev_supported_types/nvidia-286/create
  1. 如果賦予多個UUID,等同建立多個虛擬GPU,讓不同的虛擬機使用。

  2. 查看mdev裝置狀態

ls -l /sys/bus/mdev/devices/
  1. 如果要移除裝置就傳入1
echo 1 > /sys/bus/pci/devices/0000:01:00.0/填入UUID/remove

6. 修改vGPU overrides數值
#

編輯/etc/vgpu_unlock/profile_override.toml

控制要分配給虛擬機的VRAM大小,我這裡是設定2GB。你可以給多個虛擬機均分GPU。

# 全域設定
[profile.nvidia-286]
num_displays = 1
display_width = 1920
display_height = 1080
max_pixels = 2073600
cuda_enabled = 1
frl_enabled = 1
framebuffer = 0x74000000
framebuffer_reservation = 0xC000000

# 個別設定:mdev的UUID為vGPU mdev的UUID
[mdev.3613e491-7ff6-4e26-bab0-c6209306f0f4]
num_displays = 1
display_width = 1920
display_height = 1080
max_pixels = 2073600
cuda_enabled = 1
frl_enabled = 1
framebuffer = 0x74000000
framebuffer_reservation = 0xC000000

7. 將顯示卡分配給KVM虛擬機
#

  1. 安裝Libvirt和Windows 11虛擬機

  2. 編輯虛擬機,點選編輯XML

  3. </devices>之前加入段落,添加mdev裝置。UUID1即為剛剛給vGPU賦予的UUID

<hostdev mode="subsystem" type="mdev" managed="no" model="vfio-pci" display="on">
  <source>
    <address uuid="填入UUID1"/>
  </source>
</hostdev>
  1. 開機後,Linux Guest和Windows Guest皆需要安裝特製版 Nvidia GRID driver

  2. 架設偽裝Nvidia認證伺服器的 FastAPI-DLS,並讓虛擬機連線取得授權

  3. 開啟裝置管理員和工作管理員,確認虛擬機認得到GPU型號。

參考資料
#

相關文章

透過Intel GVT-g虛擬化技術,分配Linux宿主機的GPU資源給QEMU/KVM虛擬機使用
分類   資訊科技 虛擬機與容器技術
標籤   GPU Virtualization Ubuntu
QEMU/KVM虛擬機Nvidia雙GPU直通,Linux Host對Linux Guest
分類   資訊科技 虛擬機與容器技術
標籤   GPU Passthrough PCI Passthrough QEMU-KVM Nvidia Linux
Arch Linux如何將Nvidia GPU直通給Windows QEMU/KVM虛擬機
分類   資訊科技 虛擬機與容器技術
標籤   GPU Passthrough Arch Linux QEMU-KVM

留言板

此處提供二種留言板。點選按鈕,選擇您覺得方便的留言板。要討論程式碼請用Giscus,匿名討論請用Disqus。

這是Giscus留言板,需要Github帳號才能留言。支援markdown語法,若要上傳圖片請貼Imgur或Postimages。您的留言會在Github Discussions向所有人公開。

這是Disqus留言板,您可能會看到Disqus強制投放的廣告。為防止垃圾內容,有時留言可能會被系統判定需審核,導致延遲顯示,請見諒。若要上傳圖片請善用圖床網站。