You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

内核模块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访问指针时会触发内核错误。

修复后的预期流程

  1. 父进程初始化kta_left_motor里的completion
  2. 创建kthread并传递&kta_left_motor指针
  3. kthread通过指针访问原始completion,调用complete()发信号
  4. 父进程的wait_for_completion()收到信号,继续执行,打印出Module: Completion done.

内容的提问来源于stack exchange,提问作者UndergroundCoding

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:38:08