虚拟机飞牛核显直通问题
1 报错原文
使用虚拟机运行飞牛,并直通核显后,在ssh内运行:
dmesg
出现如下报错:
[ 85.583294] i915 0000:00:06.0: [drm] *ERROR* VBT claims to have both internal and external displays on PHY A. Configuring for internal.
也有可能出现:
[ 95.808368] ------------[ cut here ]------------
[ 95.808371] i915 0000:00:06.0: [drm] drm_WARN_ON(!timeout_expected)
[ 95.808444] WARNING: CPU: 1 PID: 142 at drivers/gpu/drm/i915/display/intel_display_power_well.c:283 hsw_wait_for_power_well_enable+0x162/0x170 [i915]
...(省略一大堆)
[ 95.810991] ---[ end trace 0000000000000000 ]---
dmesg 命令直接从内核环形缓冲区中读取数据,因此它显示的是系统启动以来的内核消息。实测,在较长时间的内核消息如此大量输出后,可能会占满内核环形缓冲区导致卡死。
2 现有解决方案
目前网络上的方法有
- 修改i915驱动相关配置,让其停止向内核输出错误。(实测没用)
- 修改qemu相关配置。(我是群晖,不知道咋修改😭)
- 在rr界面里修改i915配置。(帖主试过没用)
- 导出 vbios 并设置 romfile,出处同上。(提出的人也没试过😇)
总之目前搜到的四种方法并不能解决这个问题,本文在这里提出一种新办法,可以较好的解决。
3 截流改道法
《后汉书》记载:
景陈其利害,应对敏给,帝善之。又以尝修浚仪,功业有成,乃赐景《山海经》《河渠书》《禹贡图》及钱帛衣物。夏,遂发卒数十万,遣景与王吴修渠筑堤,自荥阳东至千乘海口千余里。景乃商度地势,凿山阜,破砥绩,直截沟涧,防遏冲要,疏决壅积,十里立一水门,令更相洄注,无复溃漏之患。
东汉水利专家在治理黄河时,对水流进行了裁弯取直,用堤坝把它截断,让水按照他规划的新路线流。
类似的,我们也可以对内核消息进行截断,让内核消息流进我们指定的一个文件内,不再过多占用内核环形缓冲区、内存。
首先先创建三个文件
/usr/local/bin/dmesg-logger.sh 进行日志收集
#!/bin/bash
# 配置文件
LOG_FILE="/var/log/dmesg.log"
dmesg -c -T >> "$LOG_FILE"
/etc/systemd/system/dmesg-logger.service 日志收集服务配置
[Unit]
Description=Dmesg Log Rotation Service
DefaultDependencies=no
After=sysinit.target local-fs.target rc-local.service
Before=shutdown.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/dmesg-logger.sh
[Install]
WantedBy=multi-user.target
/etc/systemd/system/dmesg-logger.timer 用于定时启动日志收集服务
[Unit]
Description=Run dmesg-logger every half hours
[Timer]
OnBootSec=1min
OnUnitActiveSec=30min
AccuracySec=30s
[Install]
WantedBy=timers.target
然后运行
# 默认以root权限运行,用户自己加sudo
chmod +x /usr/local/bin/dmesg-logger.sh
systemctl daemon-reload
systemctl enable dmesg-logger.timer
systemctl start dmesg-logger.timer
systemctl status dmesg-logger.timer # (可选)检查一下定时
systemctl start dmesg-logger.service # (可选)测试一次
4 效果
在 /var/log/dmesg.log下可以看到目前已经被转移的所有内核日志。

图1 效果图
参考文献
- 飞牛论坛Leo_L95NF帖子
- Github rr issue