使用rmmod命令移除内核模块时报Device or resource busy的问题
在Linux下为PCI设备写驱动程序,发现insmod插入内核模块正常,但是rmmod时出错,报下面的错误:
rmmod: ERROR: could not remove 'xxxxxx': Device or resource busy
rmmod: ERROR: could not remove module xxxxxx: Device or resource busy
使用lsmod可以看到此模块的Used by是0,一开始怀疑是自己的代码有问题,于是精简了一个最基本的框架,代码如下:
1 #include <linux/init.h> 2 #include <linux/module.h> 3 4 static int __init demo_init(void) { 5 printk(KERN_INFO "DEMO_INIT"); 6 return 0; 7 } 8 9 static void __exit demo_exit(void) { 10 printk(KERN_INFO "DEMO_EXIT"); 11 } 12 13 module_init(demo_init); 14 module_exit(demo_exit);
编译后仍然是insmod正常但rmmod报错,奇怪的是换一台机器就好了,于是开始比对两边环境的差异。正常的环境是CentOS-7.9-x86_64,内核版本3.10.0,gcc版本4.8.5。异常的环境是CentOS-7.9-aarch64,内核版本4.18.0,gcc版本4.8.5。差异在于内核和CPU架构。
于是开始怀疑可能是系统的锅,多方查找,最后发现是编译时使用的gcc与系统gcc版本不一致导致的,在异常的环境上查看:
[root@centos145 ~]# dmesg | grep gcc
[ 0.000000] Linux version 4.18.0-193.28.1.el7.aarch64 (mockbuild@aarch64-01.bsys.centos.org) (gcc version 8.3.1 20190311 (Red Hat 8.3.1-3) (GCC)) #1 SMP Wed Oct 21 16:25:35 UTC 2020[root@centos145 ~]# gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/aarch64-redhat-linux/4.8.5/lto-wrapper
Target: aarch64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-aarch64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-aarch64-redhat-linux/cloog-install --enable-gnu-indirect-function --build=aarch64-redhat-linux
Thread model: posix
gcc version 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
可以看到gcc分别是8.3.1和4.8.5。而正常的环境上两者是一致的,均为4.8.5。升级一下gcc应该可以解决,后续可以试下。至于有没有其它方案有待研究。