内核模块kthread completion实现异常:父进程无法唤醒问题排查
问题分析与修复方案
嘿,我一眼就揪出问题所在了——你在kthread里错误地拷贝了传入的参数结构体,导致complete()操作的是一个局部副本,而不是父进程中初始化的那个completion对象,这就难怪父进程永远等不到唤醒信号了!
问题根源
在motor_rotate函数里,你写了这么一行:
kthread_arg in = *(kthread_arg*)data;
这行代码会把传入的kta_left_motor结构体完整拷贝到kthread栈上的局部变量in里。后续你调用complete(&in.wait_for_motor)时,实际是给这个局部的completion发信号,但父进程里wait_for_completion(&kta_left_motor.wait_for_motor)等待的是完全独立的另一个completion实例,两者根本不互通,父进程自然会一直挂起。
修复步骤
只需要修改motor_rotate函数,不要拷贝结构体,直接使用指针访问原始结构体:
修改后的motor_rotate函数
static int motor_rotate(void* data) { // 直接使用指针访问原始结构体,不要拷贝 kthread_arg *in = (kthread_arg*)data; int i = in->side; printk(KERN_NOTICE "Module: motor side=%d\n",i); printk(KERN_NOTICE "Module: Completing kthread...\n"); // 操作原始的completion结构体 complete(&in->wait_for_motor); printk(KERN_NOTICE "Module: Kthread Completed.\n"); return 0; }
额外注意事项
你在main_init里把kta_left_motor声明为static是非常正确的做法——static变量的生命周期会贯穿模块加载的整个过程,避免了kthread运行时结构体被销毁导致的野指针问题。如果这里不用static,kta_left_motor会在main_init执行完毕后被释放,kthread访问指针时会触发内核错误。
修复后的预期流程
- 父进程初始化
kta_left_motor里的completion - 创建kthread并传递
&kta_left_motor指针 - kthread通过指针访问原始completion,调用
complete()发信号 - 父进程的
wait_for_completion()收到信号,继续执行,打印出Module: Completion done.
内容的提问来源于stack exchange,提问作者UndergroundCoding
相关产品推荐
相关产品推荐

