# Ubuntu、麒麟 GPU 链路优化实施记录 实施日期:2026-11-11。依据桌面上的《麒麟与Ubuntu云桌面画质帧率及延迟对齐说明_20261110.docx》,以及用户补充的“允许三桌面轮流使用同一块 GPU”。原 Word 文档保留为实施前说明。 ## 已实施的链路 宿主为 i7-4720HQ,4 个物理核、8 个逻辑线程,约 23.35 GiB 内存。GTX 965M 2 GiB 是本轮三桌面轮流使用的设备。HD 4600 没有可用 mdev,不按共享 vGPU 处理。Ubuntu、麒麟各配置 8 vCPU、8 GiB;8 vCPU 不等于新增 8 个物理核。 | 项目 | Ubuntu VM102 | 麒麟 VM101 | | --- | --- | --- | | 会话 | GNOME Xorg、test2 自动登录 | UKUI / ukui-kwin_x11、test1 自动登录 | | 渲染 | GTX 965M,glxinfo 与进程显存使用均已核实 | GTX 965M,glxinfo 与进程显存使用均已核实 | | 驱动 | Ubuntu 官方 580.178.04 | 麒麟官方 580.95.05 | | 实际捕获/编码 | NvFBC / CUDA / h264_nvenc | NvFBC / CUDA / h264_nvenc | | 显示路径 | NVIDIA 渲染,modesetting PRIME 输出;虚拟源屏测试提高至约 119.9 Hz | NVIDIA 固定 2560×1440 整屏,无 RandR 物理输出 | | 串流交付档位 | 2560×1440、45 FPS、25 Mbps、H.264 SDR | 2560×1440、45 FPS、25 Mbps、H.264 SDR | | 光标 | 保留系统原生形状、本地移动和租约协议 | 保留系统原生形状、本地移动和租约协议 | Sunshine 固定为 v2025.924.154138。当前 2026 构建在 Maxwell 上实际出现 CUDA kernel 不兼容,不能仅因为版本更新就替换。私有程序位于 `/opt/vdi-sunshine-maxwell/`,用户服务为 `vdi-sunshine.service`。旧的软件编码绑核已清除;未将整个 Sunshine 改为 SCHED_FIFO,也未把关闭提示音、窗口居中当作视频优化。 Ubuntu 尝试无 RandR 输出的 NVIDIA 整屏路径时,GNOME 实际黑屏,已回退到可用 PRIME 输出;它仍含显示复制,不能称全程零拷贝。麒麟旧内核的 PRIME 显存导入失败,改用驱动实际报告的整屏 NvFBC 捕获。适配器只在真实屏幕为 2K、驱动可采集且没有输出时枚举整屏,不伪造物理显示器或硬件支持。麒麟重启后桌面曾自动改大屏幕,已通过 ServerFlags 禁用自动添加/绑定其他 GPU,并固定 X screen。 麒麟 glibc 2.31 与该官方 Sunshine 构建不兼容,因此程序使用私有 runtime 的加载器和依赖库,未替换系统 glibc。初始依赖经 Ubuntu APT 签名仓库核对;补充的 libwayland-client、libffi8、libva 来自 Ubuntu 官方 HTTPS 仓库并记录下载散列,但本轮未额外完成它们的 APT 签名索引校验。KYSEC 保持开启,仅对本轮文件进行 verified 认证。 ## 操作方式与隔离 平台设置 `VDI_EXCLUSIVE_GPU_NODE=starhe`、`VDI_EXCLUSIVE_GPU_VMIDS=100,101,102`。盒子退出串流后,选择下一台即可正常关闭上一台、等待 PVE 原任务和实际 stopped 状态、启动目标,再等待 Sunshine 响应。不会为了快速切换强制断电。**退出串流并不立即关闭虚拟机;选择另一台时才正常关闭上一台,因此切换前须保存当前桌面的工作。** 准备任务需要该终端已有桌面授权。共享组锁、持久任务预约、会话占用检查阻止相互抢占;票据签发和消费再次查实际 PVE 电源状态,不能依赖旧缓存。正在使用或管理任务未完成时拒绝切换。已知 PVE 操作结果不明时保留占用,管理员仅核对原 UPID,不自动重复提交。终端不接收 PVE root 凭据。 准备接口:`POST /api/v1/terminal/desktop-prepare`、`GET /api/v1/terminal/desktop-prepare/:id`。已知任务核对:管理员 `POST /api/v1/tasks/:id/gpu-reconcile`。未知 UPID 须人工核对 PVE 与任务记录,不能凭“现在看起来已开机”重发电源操作。管理端对共用组的普通 start/reboot 入口拒绝执行,须从终端选择页准备;正常 shutdown 及规格、快照操作受同一组预约约束。 Ubuntu 为唯一 onboot=1 的桌面,Windows 与麒麟 onboot=0,避免宿主启动时争用显卡。该模式是整卡轮流直通,不是三会话同时使用。将来迁移算力服务器仍需提供真正可并发的 GPU/编码会话容量,不能只提高显卡算力或显存就默认支持多 VM 共享。 客户端新增受范围校验的 `VDI_MOONLIGHT_BITRATE_KBPS`;盒子 `~/.config/vdi-terminal/render.conf` 的 `bitrate_kbps=25000` 由启动脚本按允许字段读取,不执行配置内容。缺少配置时继续使用原分辨率对应默认码率;本轮最终实际命令行已核实 25000。25 Mbps 是客户端请求档位,不等于持续视频净码率;Ubuntu 本轮 Sunshine 记录的视频编码预算为 18,988,000 bit/s,不能将二者混同,也不能用启动探测时的 1 Mbps 当作实际串流档位。 ## 测量口径 拖框使用同几何和逐帧序号的 GTK / WinForms 参考窗口;盒子通过 XTest 注入,XGetImage 观察首次解码回显。一次拖框发送 300 次移动并检查松键。读取画面本身会阻塞发送循环,不能称真正恒定 60 Hz,也不能把“观察到的新画面次数”当作 Moonlight 呈现 FPS。 悬停、点击、掩码输入各 100 次,实际控件触发后更新唯一标记。点击计时从按下开始,包含人为 40 ms 按住时间;`click_release` 字段不能误读为从松键起算。输入为合成字符,无真实密码;提交页没有后台认证,所以不代表真实网站登录耗时。结果不包含 USB、真实面板扫描和人眼感知,不能作为物理零延迟证明。 ### 早期与中间结果(30 Mbps,非最终验收) | 配置 / 证据 | 拖框 P50 | P95 | 说明 | | --- | ---: | ---: | --- | | Ubuntu GPU、60 FPS | 124.14 ms | 157.50 ms | `ubuntu-gpu-60-drag.json` | | Ubuntu GPU、45 FPS、源屏约 60 Hz | 126.60 ms | 159.28 ms | `ubuntu-gpu-45-drag.json` | | Ubuntu GPU、45 FPS、源屏约 120 Hz | 97.59 ms | 128.94 ms | `ubuntu-gpu-source120-drag.json`;源屏提高频率,传输仍 45 FPS | | 麒麟 GPU、60 FPS | 83.26 ms | 106.79 ms | `kylin-gpu-60-drag.json` | | 麒麟 GPU、45 FPS | 81.22 ms | 101.44 ms | `kylin-gpu-45-drag.json` | | Windows 旧参考 | 125.64 ms | 160.10 ms | `windows-baseline-drag.json`;测量时另一 VM 在驱动编译,不能用于宣称追平 | `kylin-gpu-45-response.json` 的悬停 / 点击 / 掩码输入 P50 分别为 97.36 / 140.17 / 78.58 ms,P95 为 118.29 / 163.32 / 99.56 ms。`ubuntu-gpu-45-response.json` 为源屏 60 Hz 的中间结果,且网络延迟变化较大;不能与不同阶段网络条件混用。源屏 120 Hz 的一次 100 事件复测被 Wi-Fi 断开打断,该失败轮次不计入成功结果。 ### 同档最终复测(45 FPS、客户端请求 25 Mbps) 各项为 P50 / P95,单位 ms。Windows 窗口实际由 WinForms 生成,Linux 为 GTK;JSON 中通用 method 文本仍写 GTK,应按这里解释。各系统顺序测量,无线环境并非严格恒定,因此只代表本轮观测,不能把所有差值归因于单一设置。 | 配置 | 拖框 | 悬停(100 次) | 点击(100 次) | 掩码字符(100 次) | | --- | ---: | ---: | ---: | ---: | | Windows | 84.88 / 121.39 | 63.63 / 101.82 | 141.37 / 153.49 | 90.05 / 105.07 | | 麒麟,保留 XRender | 80.61 / 100.55 | 98.34 / 116.50 | 139.13 / 159.49 | 80.01 / 104.13 | | Ubuntu,源屏约 120 Hz、定时捕获 | 91.38 / 117.43 | 118.43 / 151.82 | 174.60 / 211.69 | 88.02 / 120.11 | 原始证据分别为 `windows-final25-*`、`kylin-final25-*`、`ubuntu-final25-*`。拖框延迟已接近同档 Windows;麒麟悬停仍慢约 35 ms,Ubuntu 定时捕获时悬停慢约 55 ms、点击慢约 33 ms,不能宣称所有交互均已追平。Windows 悬停最大值还出现 845.91 ms 的孤立尖峰;P95 不能代替长稳验收,也不能隐去最大值。 麒麟额外测试 OpenGL 合成及 MaxFPS/RefreshRate=120:必须通过实际 D-Bus `compositingType=gl2` 才能生效,单改 Backend=OpenGL 会被系统恢复。实际 supportInformation 曾确认 NVIDIA OpenGL;其 Placeholder 源屏仍报告 60 Hz,不能声称变成真实 120 Hz 输出。拖框 97.07 / 109.11 ms,悬停 98.99 / 119.18 ms,点击 143.34 / 165.30 ms,未见收益,已恢复 `kwin-before-opengl120.conf`,不作为最终方案。证据保留为 `kylin-opengl120-25-*`。 Ubuntu 又测试仅在原生光标租约内启用 NvFBC `bPushModel=true`,由画面 damage 事件生成可采集帧,保留原 direct-capture 参数,不提高视频传输帧率。接口边界 14 情形通过、真实采集成功;拖框 81.42 / 99.50 ms,但悬停 119.14 / 156.67 ms、点击 172.05 / 250.00 ms、掩码输入 79.85 / 123.18 ms,未形成一致收益。测试期间还发生 AP 切换和断流,不能将拖框改善单独归因于 push。该实验的服务环境、适配器与 manifest 均已恢复,实验选项没有留在生产代码中;原始数据为 `ubuntu-push25-*`,不得将其当作当前保留配置的性能。回退后再次实际连接、核验 manifest、`nvfbc-v1`、2K/119.9 Hz 与硬件编码负载均通过。 ### GPU 切换实测 已从选择页完成 Ubuntu→麒麟、麒麟→Windows、Windows→麒麟、麒麟→Ubuntu 的完整轮转。准备任务分别约 33、66、34、30 秒,含正常关机、开机和 Sunshine 就绪。最后一次 Ubuntu 冷启动后核对真实 2560×1440、约 119.9 Hz 源屏、NvFBC receipt 和 NVENC 编码负载均正常;桌面实际截图见 `ubuntu-final-desktop.jpg`,麒麟见 `kylin-final-desktop.png`。任务记录见 `gpu-switch-tasks.csv`,其中同一台重连的短任务不代表冷启动耗时。 实验重启 Sunshine 时另有一次准备任务在最终归属复核处失败,正常释放失败任务后,重新由用户界面准备成功;没有绕过复核或重复发送未知电源任务。不能把全部准备尝试描述为零失败。收尾仅 Ubuntu 运行,Windows、麒麟停止,盒子退出至选择页。 ## 仍限制体验的部分 盒子是 RK3528,使用 RKMPP 硬解、DRM PRIME / NV12 帧和 EGL 呈现。60 FPS 串流实际接收/解码约 60,但呈现约 43,约 28% 帧被丢弃;盒子 GPU 曾达到 800 MHz 下约 90% 使用率。45 FPS 测试实际呈现约 43~44,排队和丢帧更少。客户端将部分“丢弃旧帧”记在 network jitter 栏,不能把这一栏全解释为 Wi-Fi 丢包。当前不构成稳定 2K60,也未完成直接 DRM scanout 绕开 GPU 合成的实现。 盒子当前走 5 GHz Wi-Fi,有线端口 NO-CARRIER。串流期间已发生 Wi-Fi 真正断开和重新关联,wpa_supplicant 原始记录含 reason=34 与关联拒绝;不是 Linux 编码器重启的推测。12:33、12:44 等记录还显示同 SSID 下尝试 2.4 GHz 接入失败,再关联 5 GHz;本轮没有修改路由器或锁定 BSSID。无线驱动为 `aicwf_sdio`,省电已关闭。网络延迟在不同测试从约 5 ms 上升到 16~40 ms,原生光标通道因此超时并正常结束串流。没有通过延长超时掩盖断网。证据见 `wifi-final.log`、`client-final.log`。提高服务器 GPU 算力不能消除盒子断网;下一步应优先让宿主与盒子稳定有线连接,再做同条件验收。 本轮核查宿主温度曾达 87~88°C,盒子约 76°C,需结合持续负载观察。存储 local 约 74.2%,local-lvm 约 93.8%,后者仅约 3.9 GiB 余量;未创建大快照或继续堆积大备份。迁移/扩容和稳定散热是长期运行条件,不能用持续写满测试验证性能。 收尾清理 Ubuntu 可再生成的 APT 安装缓存,约 772 MiB 降到 40 KiB,并执行根分区 fstrim。fstrim 报告的是发出的逻辑范围(约 28.4 GiB),不是宿主实际回收量。复查发现 Ubuntu 磁盘实际在 local 的 qcow2 文件中,local-lvm 实际使用率仍为 94.04%,不能宣称薄卷空间已释放。未删除系统、用户文件、回退备份或擅自扩大薄卷逻辑容量。 尚未完成 Word 文档提出的 10 分钟统一业务动态场景、每类 100 次真实拖窗/应用启动、物理相机延迟,以及 2 小时 / 8 小时长期验收。存在已捕获的 Wi-Fi 断流,故不得宣称已完成长稳或“全部操作与 Windows 完全相同”。 ## 代码验证与回退 - 专用空测试数据库 `vdi_gpu_test_20261111`:共享组授权/占用、先关后开、缓存滞后票据、电源结果不明不重放、硬拒绝、原 UPID 核对和管理操作互斥。见 `exclusive-gpu-test.log`。该测试会清空自己的 fixture,严禁改为 live 数据库运行。 - 实际盒子编译并运行 6 项 CTest,含关机桌面可点、准备成功前不签发票据、失败不连接和码率范围验证。见 `kiosk-tests.log`。 - 麒麟实际 glibc 上,NvFBC ABI / 原参数不变 / 租约光标 / 整屏枚举 / 错版本拒绝等 10 情形通过。 - 两台 Linux 分别通过 host 回归:显示管理器重启后的旧就绪标记清除、manifest 不完整时不触碰运行中的捕获服务;本地 4 项光标输入边界测试通过。 - OpenAPI 与 TypeScript 类型已更新;控制台 typecheck 通过。Hardware、Snapshot、PowerBatch、DeviceIdentity、TerminalLifecycle 的专用数据库回归完整通过(344 秒),见 `maintenance-regressions.log`。 ## 当前结论和下一步条件 ### 后续修复:Ubuntu 双光标(2026-11-11) 用户反馈“一支鼠标拖着另一支”。现场核对:原生光标租约、适配器和 `nvfbc-v1` 均生效,但盒子根窗口截图仍能看到视频内箭头。原先仅确认 NvFBC 关闭光标参数和捕获就绪,未覆盖 PRIME 路径已将服务端软件光标画入画面的情形;这使本地即时光标与有视频延迟的光标叠加。 已在 Ubuntu 部署 guard 生命周期内的 XFixes 服务端光标隐藏,原生形状读取和盒子本地显示继续保留。配置标记是 `/home/test2/vdi-terminal/native-cursor-v1/hide-server-cursor`,未修改光标主题、移速、分辨率或编码档位。结束时先停视频生产者,再恢复服务端光标,显示连接断开也会释放隐藏状态。变更前 Python 文件备份在 `/var/backups/vdi-gpu-20261111/host-before-serverhide.py`。 Ubuntu 真实运行 3 项 host 回归全部通过,含捕获失败时停止/恢复顺序。盒子在三处纯桌面背景比较移动前后同一位置:超过 25 的通道变化像素数均为 0,最大通道差 0/1/0;同时本地原生光标保持 24×24、热点 (3,1)、254 个非透明像素,位置正确。见 `ubuntu-double-cursor-check.json`;该截图口径排除本地 X11 光标,因此用于检查视频中是否还有箭头,不冒充相机拍摄。随后 300 次拖框移动全部收到且松键成功,见 `ubuntu-cursorfix-drag.json`。退出后检查普通捕获已恢复、lease ready/drop-in 已清理;重新连接后重复三处检查仍通过,见 `ubuntu-double-cursor-reconnect.json` 和 `ubuntu-cursorfix-tests.log`。收尾保留 Ubuntu 串流供用户使用。这些检查用于验证重复光标和输入功能,不替代物理延迟或长稳验收。 已经实现三台轮流直通同一块 GTX 965M,Ubuntu、麒麟实际使用 GPU 渲染、NvFBC 捕获和 NVENC 编码;本轮不再依赖 4 核 CPU 承担 2K 软件编码。2K 画幅与 H.264 SDR 档位已对齐,拖框测得接近同档 Windows;当前保留的 Ubuntu 悬停、点击和麒麟悬停仍有可测差距,且反复出现无线断流,尚不满足“所有交互及长期稳定性与 Windows 一致”。分辨率相同也不等于已完成色彩或文字画质的客观一致性验收。 下一步应先给盒子接通稳定有线网络,宿主也保持有线;在固定网络、相同业务场景下重测并区分 GNOME/UKUI 重绘、显示复制与客户端呈现耗时,再决定是否重新试验事件触发捕获。若目标保持真 2K60,现有 RK3528 的 EGL 呈现路径还需继续减少复制/合成,或换实测可稳定 2K60 呈现的终端。当前 GTX 965M 已能完成单桌面硬编码,继续只加 VM CPU 核数不能解决无线断流和盒子呈现上限。 未来要求三个桌面同时运行时,需规划各 VM 可独立使用的物理 GPU,或硬件、驱动及授权均支持的 vGPU/编码方案,并按并发会话数验证;当前轮流直通方案不能直接变成同时共享。正式迁移前还应处理薄卷池余量与散热,再补齐 Word 中的长期及物理延迟验收。 PVE 变更前配置保存在 `/root/vdi-linux-gpu-20261111/{100,101,102}.conf.before`;Linux 备份在各自 `/var/backups/vdi-gpu-20261111/`。Ubuntu 的 headless 失败试验、PRIME 配置和提高源屏频率前脚本均有独立备份。回退显示配置时先退出串流,恢复对应 Xorg 与显示脚本,再正常重启显示管理器;必须目视确认桌面,不能只查服务 active。 平台部署前 API 镜像保留为 `vdi-cloud-live-api:before-gpu-20261111`,环境备份为工作站 `.local/live/env.before-gpu-20261111.bak`,不含于报告或仓库。盒子变更前文件在 `~/vdi-build/gpu-opt-20261111/`。回退共享组前先确认只有一台持有显卡,停用两项 group 环境变量并恢复 API/客户端;不要在 GPU 仍被别台使用时直接开机。 ## 官方依据 - [Sunshine 配置](https://docs.lizardbyte.dev/projects/sunshine/latest/md_docs_2configuration.html)、[发行记录](https://github.com/LizardByte/Sunshine/releases)。实际使用选项按已装版本核验。 - [NVIDIA Xorg 配置选项](https://download.nvidia.com/XFree86/Linux-x86_64/580.82.09/README/xconfigoptions.html)。 - [Proxmox PCI 直通说明](https://github.com/proxmox/pve-docs/blob/master/qm-pci-passthrough.adoc)。 设备能枚举、编码测试能启动和完整交互桌面可用是不同证据;本报告按真实串流、GPU 编码负载和画面核验分别记录。 ## 补充:Windows 硬编码故障与恢复(2026-11-11) 用户反馈 Windows 鼠标卡顿后,实际查到 GTX 965M 的设备管理器错误码为 43,`nvidia-smi` 无法连接驱动;Sunshine 13:38 的真实连接日志为 `Creating encoder [libx264]`,并非 NVENC。这是独立于 Ubuntu 双光标的故障,不能用鼠标移速或无线网络解释全部表现。 与原 PVE 备份比对,Windows 的 CPU、内存、PCI 直通和 QEMU 参数一致,只有 `onboot: 1→0`。公共客户端请求码率曾从 30 改为 25 Mbps,对 Windows 也有影响;45 FPS 在 11 月 9 日的客户端日志中已存在。Windows 内曾执行临时交互参考测试,相关计划任务已清理。本次排障还重启过显卡设备、Sunshine 服务,并在用户允许后正常关开机;不能描述为“Windows 内完全没有操作”。Ubuntu 隐藏服务端重复光标的补丁没有部署到 Windows。 显卡设备重启、Windows 正常关开机和宿主侧专用 PCI 总线复位均未恢复 NVENC;总线复位后宿主曾显示 D0,但 Windows 启动后又报 Code 43,物理设备显示 D3hot,尚不能据此单独确定驱动失败的根因。用户随后明确同意正常重启整台 Proxmox 宿主;执行前再次检查三台 VM 和容器列表、备份 Ubuntu 配置,将仍为 1 的 Ubuntu `onboot` 改为 0,避免宿主恢复时自动争用显卡。先正常关闭 Windows,确认三台全部停止后提交宿主重启。 当前排他切换只核验电源归属和 Sunshine `serverinfo`,不能证明 NVIDIA 驱动与硬件编码健康。此前完成过轮转不代表已证明长期可重复可靠;在恢复后完成跨系统重切和真实 NVENC 验证前,不应宣称该共享显卡方案已通过稳定性验收。禁止仅凭“连接服务已响应”报告硬编码恢复。 ### Windows 恢复结果(13:44—13:47) 宿主启动 ID 已从 `f078a704-350d-4c7d-8839-c192ebe7c4b5` 变为 `df157c5a-ae91-4225-b4b7-f6ab8c0ed8c9`,确认实际完成宿主重启。随后从盒子启动 Windows,NVIDIA 设备错误码恢复为 0,`nvidia-smi` 正常返回 GTX 965M / 582.78。13:44:44 实际连接为 `Creating encoder [h264_nvenc]`,随后明确创建 H.264 P1 编码器;连续检查 GPU 编码负载约 10%—11%,Sunshine CPU 采样为 0%,不再是此前的软件编码状态。日志中的 HEVC 10-bit 探测失败不是当前流,当前流已核对为 H.264 SDR。 盒子日志确认实际串流为 2560×1440 / 45 FPS、RKMPP H.264 硬解;画面可用。完成 30 步桌面背景拖框,画面出现对应选框,finally 中释放鼠标按键,未重建 Windows 临时计划任务。证据为 `windows-recovery-nvenc.log` 和 `windows-recovery-desktop-drag.jpg`。这是短时功能与硬编码恢复核验,没有重新完成物理输入延迟或长期稳定性验收。 本次收尾状态取代前文“保留 Ubuntu”的旧状态:Windows 正在运行并连接,Ubuntu、麒麟关闭;三台 onboot 均为 0。Ubuntu 自动启动改动前备份为 `/root/vdi-linux-gpu-20261111/102.conf.before-windows-recovery`。未更换 Windows 显卡驱动,未修改其 CPU、内存、鼠标速度或直通参数。宿主重启前的 `power/control=on` 是临时状态,没有创建持久化规则。 本次恢复表明整机重新初始化后显卡可以重新供 Windows 使用,但没有证明跨系统切换失败的唯一根因,也没有修复自动切换的硬编码健康校验缺口。当前先保留 Windows 使用;不得将这次恢复表述为“共享 GPU 切换问题已彻底解决”。 ## 后续修复:Windows→Ubuntu 一直“进入中”(2026-11-11 14:07) 13:49 的 Ubuntu 准备任务在 `service-waiting` 阶段等待 180 秒后失败。Windows 已正常关闭,Ubuntu 已开机,但 Linux NVIDIA 驱动从开机起报告 `fallen off the bus and is not responding to commands`,GNOME/Xorg 会话反复失败,Sunshine 未启动。Ubuntu 内停止桌面并卸载、重载 NVIDIA 模块仍返回 `No such device`。该现象不能解释成单纯页面动画或需要重复点击。 确认 VM100/101 关闭、VM102 正常关机、VFIO 组无人持有,且上游桥只有 GTX 965M 后,对 GPU 执行 sysfs `remove`、等待两秒、桥 `rescan`,核验同一 PCI 身份、vfio-pci 驱动和 D0,再启动 Ubuntu。此次无需重启宿主即恢复 GNOME、NvFBC 与 NVENC。首次恢复任务耗时 25.41 秒。该实验与前一轮只写 PCI `reset` 不同;不能将两者混称为已重复验证过的同一方法。 为使此步骤在后续开机时自动执行,增加 `tools/pve-shared-gpu-hook.py` 并部署为 `local:snippets/vdi-shared-gpu-reset.py`,绑定 VM100/101/102。实现仅适用于 starhe 的指定 GTX 965M、PCI 桥和 IOMMU 拓扑。每次 pre-start 必须确认三台全部停止、VFIO 组无人使用;使用 flock 和开机阶段预留,避免两次准备同时穿过检查。初始化失败保留 failed 预留,后续启动被阻止,不自动重放结果未明的操作;post-start 记录归属,post-stop 核验后释放。GPU 返回 D0 只代表开机前设备条件,仍不替代来宾驱动和真实硬编码核验。 部署前备份:`/root/vdi-linux-gpu-20261111/{100,101,102}.conf.before-gpu-hook` 和 `storage.cfg.before-gpu-hook`。local 存储内容类型保留原值并增加 snippets。Windows PVE 配置此次新增 hookscript,未修改 Windows 来宾鼠标、应用、驱动或硬件资源配置;不能再用此前“仅 onboot 不同”的历史对比描述当前配置。 验证结果:4 项本地回归通过,覆盖运行/占用拦截、连续启动预留、初始化失败不重放、错误 VM 不能认领。宿主实测在 Windows 运行时调用另一个 VM 的 pre-start,会拒绝操作并报告运行者,未重置正在使用的 GPU。部署后从盒子完成 Ubuntu→Windows(73.88 秒)和 Windows→Ubuntu(41.01 秒),均未重启宿主。Windows 设备错误码为 0,实际串流 H.264 NVENC,编码负载约 11%;最终 Ubuntu 实际连接确认 NvFBC、2560×1440、H.264 NVENC,编码负载约 29%,服务 active。1 Mbps 日志属于编码探测,最终会话实际视频预算为 18.988 Mbps,客户端请求档位仍为 25 Mbps。双光标隐藏标记保持存在。 当前仅 Ubuntu 运行并留在盒子桌面,Windows、麒麟停止,GPU 预留归属 VM102/running。本轮验证了一次双向轮转,未重新测试麒麟轮转,也未完成数十次循环或长期稳定性验收;不据此保证任意次数切换均无故障。平台当前仍以 serverinfo 判断服务就绪,硬编码健康尚需另行加强,不能把本钩子说成编码健康检查。 证据:`gpu-hook-unit-tests.log`、`gpu-hook-active-guard-test.log`、`gpu-hook-switch-tasks.csv`、`gpu-hook-windows-nvenc.log`、`gpu-hook-ubuntu-nvenc.log`、`gpu-hook-final-state.log` 及两台最终桌面截图。 回退时先退出串流,并逐台确认 hookscript 当前仍为本次路径,再执行 `qm set --delete hookscript`;此操作只去掉本次钩子,不整份覆盖其他 VM 配置。保留 snippets 内容类型不会重置显卡。如出现 failed/prepared 预留,必须先核对所有 VM 实际电源、原启动任务、VFIO 占用及 PCI 设备状态,再由管理员处理 `/run/vdi-shared-gpu/reservation.json`;不要直接清空预留并反复开机。 ## 补充验证:麒麟共享显卡切换(2026-11-11 14:30) 用户要求验证麒麟。开始检查时,用户已从 Ubuntu 切到麒麟,平台初次准备耗时 37.68 秒;同机重连的 0.49 秒任务不计为冷启动。NVIDIA 580.95.05 正常,OpenGL renderer 为 GTX 965M,源画面为 2560×1440,实际连接日志确认 NvFBC 与 H.264 NVENC,GPU 编码负载约 25%。现场看到软件商店正在安装更新,先等待并核对 aptdaemon 无活动事务、包管理锁释放、`dpkg --audit` 无异常后,才开始关机轮转,未中断或主动执行软件更新。 随后从盒子完成以下四次正常关机、共享 GPU 初始化、开机和连接服务准备: | 方向 | 准备耗时 | 结果 | | --- | ---: | --- | | 麒麟→Windows | 79.31 秒 | 实际 H.264 NVENC,GPU 编码负载约 10% | | Windows→麒麟 | 40.75 秒 | NVIDIA OpenGL、NvFBC、实际 H.264 NVENC,编码负载约 22% | | 麒麟→Ubuntu | 36.82 秒 | 真 2560×1440、NvFBC、实际 H.264 NVENC,编码负载约 29% | | Ubuntu→麒麟 | 38.01 秒 | NVIDIA OpenGL、NvFBC、实际 H.264 NVENC,编码负载约 23% | 四次均成功,宿主启动 ID 始终为 `df157c5a-ae91-4225-b4b7-f6ab8c0ed8c9`,本轮没有重启宿主或修改三台 VM 的配置。耗时以平台数据库任务创建到完成计算,不包含人手退出、检查和再次点击的间隔;服务准备完成也不等于最终画面已经出现,因此另外核对实际 CLIENT CONNECTED、最终编码器、GPU 负载和桌面截图。 麒麟启动后显示过其自身锁屏,最终通过 logind 解锁当前测试会话,并核对实际桌面。未关闭锁屏策略或修改登录配置。麒麟开机早期来宾日志时间有八小时偏差,最终已核对 NTPSynchronized=yes、系统时间恢复;轮转顺序与耗时依据平台记录,日志按当前 boot 和实际 Sunshine PID 筛选,避免混入旧启动记录。未修改 RTC 或 NTP 配置。 最终盒子日志确认 2560×1440 / 45 FPS 串流、RKMPP H.264 硬解;45 是协商串流帧率,不代表重新实测了终端持续呈现 45 FPS。请求码率仍为 25 Mbps,最终视频预算为 18.988 Mbps,1 Mbps 记录属于编码器探测阶段。保留原有麒麟桌面与光标配置。 最后从盒子发送 30 步桌面背景拖框,实际解码画面显示对应选框,finally 中松开鼠标按键成功。此检查验证基本输入和视频回显,不是物理输入延迟、掉帧率或画质客观一致性测量。此次完成了麒麟与另外两台各一次双向切换,未据此宣称两小时/八小时长稳,或麒麟全部交互延迟已经与 Windows 完全一致。 收尾仅麒麟 VM101 运行并连接,GPU 预留为 VM101/running;Windows、Ubuntu 均停止。结果取代前文保留 Ubuntu 的收尾状态。 证据:`kylin-cycle-switch-tasks.csv`、`kylin-cycle-windows-nvenc.log`、`kylin-cycle-return-from-windows.log`、`kylin-cycle-ubuntu-nvenc.log`、`kylin-cycle-return-from-ubuntu.log`、`kylin-cycle-final-state.log`、`kylin-cycle-final-drag.jpg` 和 `kylin-cycle-final-desktop.jpg`。 ## 补充优化:终端调度对照与无线扫描(2026-11-11 15:43) 本轮保持 2560×1440、45 FPS、客户端请求 25 Mbps、H.264 SDR。两台实际 NvFBC / NVENC 保持有效,未调整原生鼠标样式或移速。没有修改 Windows 来宾的驱动、鼠标、应用或资源配置;为测试按平台流程正常关闭 Windows 并切到 Linux。此次持久调整在共用盒子的网络配置中,因而也影响盒子连接 Windows 时的网络路径。 ### 实际保留的调整 盒子三次无线断开记录中有 `reason=34`。15:22:58 断开后,反复尝试同名 2.4 GHz 热点并被拒绝,直到 15:23:25 才恢复 5 GHz。先仅设置 5 GHz,15:30:31 仍断开,15:30:44 恢复;说明限制频段不足以修复断开本身。 进一步将盒子现有 YXTech 配置固定到当前 5 GHz 接入点 `f8:ce:21:a7:b9:50`。NetworkManager 文档说明固定 BSSID 会禁用漫游及后台扫描;此前断开间隔约五分钟,扫描参与问题是推断,尚未证明是唯一根因。Wi-Fi 省电原本已关闭,本轮没有把它记为新增优化。 配置已通过 nmcli 写入 `/etc/netplan/90-NM-9212612f-4dd0-4cf0-a21b-85413c900acf.yaml`,核对 `band: 5GHz` 和 BSSID。每次试验前设置了 90 秒自动回退,重连和 SSH 验证成功后取消回退;没有留下活动回退定时器。配置备份位于盒子 `/var/backups/vdi-wifi-20261111/`,不是 PVE,备份不复制到仓库以免带入无线凭据。 15:32:29—15:43:09 的约 10 分 40 秒观察中,没有再次出现无线断开或关联拒绝,越过两个此前约五分钟的周期。期间主动切换麒麟、Ubuntu并重连,不是同一桌面连续串流十分钟,也不是长期稳定性验收。若移动盒子、更换接入点或该 AP 不可用,需解除 BSSID 限制;本轮没有改路由器。 ### 未保留的调度试验 确认 SDL 渲染线程申请高优先级因权限失败。先由 root 仅把当前 Moonlight 的 PacerRender 线程从 nice 0 临时改为 -10,保持普通 TS 调度;未使用 SCHED_FIFO、文件 capabilities、全进程提权或更改用户权限上限。固定接入点后,两台分别在同一连接内顺序 A/B,每类 50 次。表内为 P50 / P95,单位 ms: | 系统 | PacerRender nice | 悬停回显 | 点击回显(含40ms按住) | 掩码字符回显 | | --- | ---: | ---: | ---: | ---: | | Ubuntu | 0 | 122.5 / 141.6 | 173.0 / 195.6 | 83.7 / 120.5 | | Ubuntu | -10 | 121.7 / 151.0 | 172.8 / 213.7 | 79.1 / 105.9 | | 麒麟 | 0 | 103.1 / 127.6 | 147.0 / 165.5 | 81.9 / 103.6 | | 麒麟 | -10 | 101.3 / 121.3 | 146.5 / 172.8 | 86.1 / 99.6 | 悬停及点击中位数没有稳定收益,部分 P95 反而上升,因此两台试验均恢复 nice 0,没有持久化提权。Ubuntu 固定 AP 前另有两轮 A/B,同样没有一致收益;被断网打断的 A2、B2 与麒麟第一次 B 不计为完整结果。不能把警告消失或某一类输入的单轮改善解释为整体延迟降低。 ### 功能与呈现复查 | 系统 | 拖动回显 P50 / P95(ms) | 观察到的新位置更新/秒 | 输入验证 | | --- | ---: | ---: | --- | | Ubuntu | 90.9 / 109.8 | 35.4 | 300 次末位置可见,松键成功 | | 麒麟 | 84.4 / 106.9 | 37.2 | 300 次末位置可见,松键成功 | 以上为 XTest 输入至首次观察到唯一解码标记,排除实体 USB 鼠标和屏幕扫描;更新/秒是 60 Hz 拖动下采样到的独特位置,不等于解码或显示帧率。GTK 的合成页面提交没有业务后端,不能代表真实密码认证或应用启动耗时。 Ubuntu 在来宾内部另测本地 X11 标记,悬停中位数约 21 ms、点击约 78 ms(含40ms按住)、掩码字符约 5 ms,每类30次。它与盒子端测量路径不同,只用于区分来宾处理与串流路径,不将差值当作可直接消除的延迟。 结束前的 Ubuntu 单会话统计:接收/解码约45.03 FPS、呈现44.18 FPS、平均网络6 ms(variance栏1 ms)、解码7.67 ms、排队4.62 ms。麒麟对应会话呈现43.85 FPS。无线条件不恒定,不能将这几次统计差异全归因于固定 AP。network jitter 栏还包含客户端丢弃旧帧,不能全当无线丢包。 Ubuntu 再次退出和重连后,三处背景检查均未发现视频内重复箭头,仍有24×24的本地原生光标。临时 GTK 参考窗口已停止,桌面实际截图核验通过。 ### 深层显示链路和边界 盒子仍是 RKMPP 硬解、DRM PRIME / EGL 呈现。现场 GPU 约800 MHz、90%—93%负载,不能承诺真2K60。部署源码明确要求 DRM master 才能直接设置显示 plane;现有原生光标实现也显式要求 X11。改成 DRM 直出需要同时完成 VT/显示所有权、光标后端、退出恢复及快捷键验证。本轮没有停掉 X11 或把“Direct rendering disabled”当成一个可随意开启的选项;没有声称已实现新的直接扫描输出或完全零拷贝链路。 本轮主要消除已观察到的无效频段重试并测试固定 AP 的短期稳定性,尚未证明 Ubuntu/麒麟全部交互延迟与 Windows 相同。继续提高 CPU 核数不能解决盒子 GPU 呈现吞吐和无线驱动/AP层问题。两小时/八小时、物理相机延迟及统一真实业务场景验收仍未完成。 ### 收尾与回退 仅 Ubuntu VM102 运行并留在盒子上,Windows、麒麟停止;宿主未重启,共享 GPU 钩子和三台 VM 配置未改。Ubuntu 双光标修复、麒麟原有合成设置均保留。PacerRender / InputSend / FFDecoder 最终均为 nice 0、TS。 在盒子上解除本轮网络限制(会短暂断网): ```sh sudo nmcli connection modify uuid 9212612f-4dd0-4cf0-a21b-85413c900acf 802-11-wireless.bssid '' 802-11-wireless.band '' sudo nmcli connection up uuid 9212612f-4dd0-4cf0-a21b-85413c900acf ifname wlan0 ``` 证据:`wifi-before-5ghz.log`、`wifi-fixed-ap-final.log`、`*-sched-fixed-ap.jsonl`、`*-fixed-ap-drag.json`、`ubuntu-local-screen-response.raw`、`ubuntu-fixed-ap-client-stats.log`、`ubuntu-fixed-ap-double-cursor.json`、`optimization-host-final-state.log`。测量脚本为 `box-sched-pair.py`、`response-probe-50.py`、`guest-local-response.py`。 依据:[NetworkManager 无线配置](https://networkmanager.dev/docs/api/latest/settings-802-11-wireless.html)、[SDL Linux线程优先级实现](https://github.com/libsdl-org/SDL/blob/release-2.30.11/src/core/linux/SDL_threadprio.c),以及现场部署的 Moonlight DRM / 原生光标源码。