当前位置:   article > 正文

KVM直通GPU_kvm gpu直通

kvm gpu直通

一、简介

在生产环境中我们通常会使用docker、VMware等其他虚拟化技术,这两种技术分别在不同的环境下发挥不同的作用,有些特殊的情况下我们会用到GPU资源,但是GPU资源通常为宿主机可用的,如果说对于docker来使用的话还算比较简单,安装一个nvidia-docker2即可容器直通GPU资源,但是对于虚拟机来说就不太方便了,因此接下来的讲解以及操作就是针对于KVM虚拟来直通GPU

注意:虽然虚拟机直通GPU了,但是这种操作会导致宿主机上失去一块GPU卡。

1. 硬件条件

首先要确定主板和CPU都支持VT-d技术,即Virtualization Technology for Direct I/O(英特尔虚拟技术)。近年的产品应该都支持此技术。 在BIOS里将
还要确定要直通的显卡支持PCI Pass-through。似乎A卡对于直通的支持比N卡好,但N卡性能比A卡好,这个大家都知道。目前市面上的显卡一般都支持直通。我用过的NVIDIA 的M60和GeForce系统960,970,1080系列都支持的。注意做显卡直通需要两块显卡,一块主机用,另一块虚拟机用,主板有集成显卡的可以采用将集成显卡给宿主机,PCI的独立显卡给虚拟机用。

2. 准备工作

在BIOS将VT-d设置成enable(主板BIOS设置项名称不一样,类似于虚拟化技术的项目打开即可)。

如下是我的当前实验环境

# 查看机器系统版本
root@ubuntu:~# cat /proc/version
Linux version 5.4.0-90-generic (buildd@lgw01-amd64-054) (gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)) #101-Ubuntu SMP Fri Oct 15 20:00:55 UTC 2021
# 验证CPU是否支持虚拟化
root@ubuntu:~# cat /proc/cpuinfo | egrep 'vmx|svm'sh
# 查看是否加载kvm
root@ubuntu:~# lsmod | grep kvm
kvm_intel             170086  0
kvm                   566340  1 kvm_intel
irqbypass              13503  1 kvm
# 当前显卡信息
root@ubuntu955:~# nvidia-smi
Tue Nov 23 03:21:02 2021       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 460.91.03    Driver Version: 460.91.03    CUDA Version: 11.2     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  GeForce GTX 108...  Off  | 00000000:02:00.0 Off |                  N/A |
| 28%   48C    P0    61W / 250W |      0MiB / 11178MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
|   1  GeForce GTX 108...  Off  | 00000000:81:00.0 Off |                  N/A |
| 26%   44C    P8     9W / 250W |    607MiB / 11178MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|    1   N/A  N/A     12188      C   python                            605MiB |
+-----------------------------------------------------------------------------+
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

3. 安装KVM

root@ubuntu:~# apt-get install qemu-kvm libvirt-bin bridge-utils ubuntu-vm-builder virt-manager virtinst
# 启动服务
root@ubuntu:~# systemctl enable libvirtd && systemctl start libvirtd
  • 1
  • 2
  • 3

二、KVM直通GPU

4. 确认内核是否支持iommu

root@ubuntu:~# cat /proc/cmdline | grep iommu
  • 1

如果没有输出结果,添加intel_iommu=on到grub的启动参数,需要重启

root@ubuntu:~# vim /etc/default/grub

# If you change this file, run 'update-grub' afterwards to update
# /boot/grub/grub.cfg.
# For full documentation of the options in this file, see:
#   info -f grub -n 'Simple configuration'

GRUB_DEFAULT=0
GRUB_TIMEOUT_STYLE=hidden
GRUB_TIMEOUT=0
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT="maybe-ubiquity"sh
# 添加intel_iommu=on
GRUB_CMDLINE_LINUX="intel_iommu=on"

# 更新grub菜单文件
root@ubuntu:~# grub-mkconfig -o /boot/grub/grub.cfg
# 重启机器
root@ubuntu:~# reboot
# 开机后检查一下
root@ubuntu:~# dmesg | grep IOMMU
# 或
root@ubuntu:~# dmesg | grep -e DMAR -e IOMMU
检查VT-d(AMD芯片时是 IOV)是否工作。若没有相应输出,需要重新检查之前的步骤
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

5. 查看pci设备信息

root@ubuntu:~# lspci -nn | grep NVIDIA
02:00.0 VGA compatible controller [0300]: NVIDIA Corporation GP102 [GeForce GTX 1080 Ti] [10de:1b06] (rev a1)
02:00.1 Audio device [0403]: NVIDIA Corporation GP102 HDMI Audio Controller [10de:10ef] (rev a1)
  • 1
  • 2
  • 3

6. 查看驱动

# 02:00.0指的就是上面grep查看出来的设备信息的开头编号
root@ubuntu:~# lspci -vv -s 02:00.0 | grep driver
	Kernel driver in use: nouveau nouveau            (系统为显卡绑定的默认驱动)
root@ubuntu:~# lspci -vv -s 02:00.1 | grep driver
	Kernel driver in use: snd_hda_intel             (显卡上附带的集成声卡的默认驱动)
# 禁用显卡的默认驱动
root@ubuntu:~# modprobe -r nouveau
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

7. 将显卡从宿主机解绑定

echo的所有内容都能在上面的第5标题找到,并且标题7 8 的操作仅针对于Ubuntu系统,centos系统和Ubuntu不一样

root@ubuntu:~# modprobe vfio
root@ubuntu:~# vfio-pci
root@ubuntu:~# cd /sys/bus/pci/devices/0000\:02\:00.0
root@ubuntu:~# echo "10de 1b06" > /sys/bus/pci/drivers/vfio-pci/new_id
root@ubuntu:~# echo "0000:02:00.0" > /sys/bus/pci/devices/0000\:02\:00.0/driver/unbind
# 如下两句针对centos系统
# centos7是/sys/bus/pci/drivers/pci-stub/bind
#root@ubuntu:~# echo "0000:02:00.0" > /sys/bus/pci/drivers/pcieport/bind
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

8. 将显卡上附带的集成声卡的默认驱动接触绑定

root@ubuntu:~# cd /sys/bus/pci/devices/0000\:02\:00.1
root@ubuntu:~# echo "10de 10ef" > /sys/bus/pci/drivers/vfio-pci/new_id
root@ubuntu:~# echo "0000:02:00.1" > /sys/bus/pci/devices/0000\:02\:00.1/driver/unbind
# 如下两句针对centos系统
# centos7是/sys/bus/pci/drivers/pci-stub/bind
#root@ubuntu:~# echo "0000:02:00.1" > /sys/bus/pci/drivers/pcieport/bind
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

检查预留是否成功

root@ubuntu:~# lspci -nnv | grep -E "(^\S|Kernel driver in use)" | grep "02:00" -A 1
02:00.0 VGA compatible controller [0300]: NVIDIA Corporation GP102 [GeForce GTX 1080 Ti] [10de:1b06] (rev a1) (prog-if 00 [VGA controller])
	Kernel driver in use: vfio-pci
02:00.1 Audio device [0403]: NVIDIA Corporation GP102 HDMI Audio Controller [10de:10ef] (rev a1)
	Kernel driver in use: vfio-pci
  • 1
  • 2
  • 3
  • 4
  • 5

三、安装测试虚拟机

9. 新建虚拟机

基础过程略过,直接看硬件信息

注意:安装驱动之前首先禁用掉默认的nVidia驱动(nouveau)
root@ubuntu:~#  touch /etc/modprobe.d/blacklist-nouveau.conf
root@ubuntu:~# cat > /etc/modprobe.d/blacklist-nouveau.conf <<EOF
blacklist nouveau
options nouveau modeset=0
EOF
# 重新生成 kernel initramfs
root@ubuntu:~# update-initramfs -u
root@ubuntu:~# reboot
# 开机后进入manager管理器
root@ubuntu:~# virt-manager
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

10. NVIDIA 驱动的反虚拟机问题

转载:https://blog.csdn.net/jcq521045349/article/details/108910531

虚拟机直通GPU之后,安装好NVIDIA驱动之后,执行nvidia-smi会返回报错信息,提示Unable to determine the device handle for GPU 0000:07:00.0: Unknown Error,说是找不到设备信息,其实这是NVIDIA显卡会检查当前系统环境是虚拟机环境还是物理机环境,如果是虚拟机他会自动屏蔽掉,所以会提示这个报错

  • Windows 下安装驱动报 43 错误
  • Linux 安装驱动后,运行 nvidia-smi 无法找到显卡

在这里插入图片描述

解决办法如下:

找到虚拟机的xml配置文件,然后对其进行修改

# 首先先关闭虚拟机
root@ubuntu:~# init 0
# 回到KVM宿主机修改配置文件其目的就是为了欺骗NVIDIA的检查
root@ubuntu:~# cd /etc/libvirt/qemu/
root@ubuntu955:/etc/libvirt/qemu# vim apt-mirrors.xml
# 填写如下配置信息,value任意写12位字符
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

格式有问题,注意和截图中的对应一致

<hyperv>
  <relaxed state="on"/>
  <vapic state="on"/>
  <spinlocks state="on" retries="8191"/>
  <vendor_id state="on" value="123456789123"/>
</hyperv>
<kvm>
  <hidden state="on"/>
</kvm>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在这里插入图片描述
Windows系统

Windows的xml文件也是同样的修改方式,只不过Windows的xml文件中默认就有一些要后期添加的内容,稍作修改即可。

重启libvirtd服务

root@ubuntu:~# systemctl restart libvirtd
  • 1

11. 验证虚拟机显卡以及驱动

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Windows
win10系统这里没做测试,win7系统安装显卡驱动的时候应该会有报错windows 7 needs to install SHA-2提示缺少补丁文件,这里安装补丁文件可下载一个360安全卫士,然后利用360下载一些补丁即可。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

12.系统重启后显卡挂掉问题

如果上面的禁止nouveau驱动方法不管用,可以使用下面的这个systemd

# 脚本解决此问题
root@ubuntu:~# touch /opt/prohibit_nouveau.sh
root@ubuntu:~# cat > /opt/prohibit_nouveau.sh << EOF
#!/bin/bash
modprobe -r nouveau
EOF
root@ubuntu:~# chmod +x /opt/prohibit_nouveau.sh
root@ubuntu:~# cat > /etc/systemd/system/prohibit_nouveau.service << EOF
[Unit]
Description=prohibit_nouveau
After=network.target

[Service]
User=root
Group=root
Type=forking
ExecStart= /opt/prohibit_nouveau.sh
TimeoutSec=0
Restart=on-failure
StandardOutput=journal
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
EOF
# 设置为开机自启动
root@ubuntu:~# systemctl enable prohibit_nouveau.service
# 重启测试
root@ubuntu:~# reboot
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/146190
推荐阅读
相关标签
  

闽ICP备14008679号