Linux环境下重装NVIDIA驱动报错kernel module (nvidia_modeset) in use问题分析

Linux环境下重装NVIDIA驱动时,遭遇报错kernel module (nvidia_modeset) in use。本文排查问题原因,并由此给出了无需重启系统也可正常重装的解决方案。

Linux环境下重装NVIDIA驱动报错kernel module (nvidia_modeset) in use问题分析

1 问题描述

在Linux环境下重装NVIDIA驱动时,出现报错,原因是内核模块正在使用中kernel module (nvidia_modeset) in use,导致无法安装新驱动。

NVIDIA驱动安装的报错页面给出的解决方案是重启一下(reboot)即可。但如果是服务器环境下,有其他用户的计算任务在执行,不希望打断,能否避免重启呢?

不知道原因的情况下,直接使用rmmod nvidia_modeset卸载该内核模块时,会遭遇报错,因为正在被占用而导致无法卸载。而rmmod -f的强制卸载又存在风险,可能造成系统崩溃(system crash)。

2 原因分析

照理说,老驱动已经卸载,那么不应该存在驱动相关的内核模块仍被使用的情况。

根据提示,既然是内核模块被占用的问题,那首先通过lsmod检查内核模块的使用情况,可以查到类似的引用关系:

1
2
3
Module                  Size  Used by
nvidia_modeset 1183744 1
nvidia 19722240 1 nvidia_modeset

从中可以发现,内核模块nvidia_modeset依赖于内核模块nvidia

通过进一步检查nvidia相关进程ps -aux | grep nvidia,发现实际上是nvidia的persistence mode的守护进程占用了内核模块nvidia_modeset。而之所以有这样一个守护进程,是为了避免nvidia-smi每次唤起过慢的问题,即,通过设置sudo nvidia-persistenced --persistence-mode启用persistence mode,借助守护进程来维护记录GPU的状态,避免每次nvidia-smi都需要同步检查每一个GPU状态在阻塞等待上耗费太多时间。

3 解决方案

查出了原因,再想办法解决就容易了。

首先,通过ps -aux | grep nvidia找出使用nvidia_modeset的进程。

随后,通过sudo kill [pid]结束该persistence mode的守护进程。

通过ps进行验证,等待进程结束后,再检查lsmod就可以发现nvidia_modeset不再被占用了。

此时,通过rmmod卸载残余的nvidia内核模块,就不会再有报错了。

如此清理完内核模块后,重新执行NVIDIA驱动安装程序,即一切正常了。