先介绍一下创建线程的大致流程:在模块的初始化函数中,调用netlink_kernel_create来注册自己的netlink协议,然后返回,接收netlink消息的函数为fcluster_netlink_recv,真正的初始化操作是在接收到netlink报文后才做,创建线程的操作也是在fcluster_netlink_recv中,如下图所示:
调用kernel_thread的语句为:
kernel_thread(fcluster_rcv_handoff, NULL, 0);
按照这样的处理流程,在卸载模块时会提示
"
module is in use".
通过lsmod命令查看自己的模块,发现引用数为1(模块引用数为0时才能卸载),但是却没有看到是哪个模块在引用。经过多次的重复测试,发现问题就出现在内核线程的创建上。因为如果把kernel_thread的调用放在fcluster_init函数中,这样模块的引用数为0,模块就可以卸载。现在就可以判断,出现模块无法卸载的原因就是调用
kernel_thread创建内核线程的时机不对,或者指定的参数不对。
为了定位问题,开始在不同的情况下增加调试代码来查找问题。
第一个测试是kernel_thread放在
fcluster_init
的情况下,在
fcluster_rcv_handoff(内核线程的处理函数)、fcluster_init、
fcluster_netlink_re