我在内核模块的初始化期间创建了一个内核线程,如下所示:
static int __init module_init(module)
{
...
tdata = kmalloc(sizeof(*data));
if (!data) {
...
}
task = kthread_run(tfunc, tdata, "memtester");
if (!task) {
pr_err("memtester: Could not create new thread\n");
goto out_err
}
...
}
我卸载这样的模块:
static void __exit memtester_exit(void)
{
printk(KERN_INFO "memtester exiting");
if (task)
kthread_stop(task);
kfree(tdata);
}
并且线程函数是这样的:
int tfunc(void *data)
{
...
for (i = 0; i < some_limit; ++i) {
do_work_a();
/* Here I need to wait for delay usec */
for (j = 0; j < delay / 1000; j++) {
if (kthread_should_stop())
goto out
udelay(1000)
if (kthread_should_stop())
goto out
}
do_work_b();
}
out:
do_exit(0)
}
在线程函数中,我需要在do_work_a()
处执行某些操作,等待delay
usec,然后在do_work_b()
中执行其他操作。我的问题是,如果我想在线程运行时删除模块,系统会挂起。
我预计当我卸载模块并执行kthread_stop()
时
在某些时候,线程将执行kthread_should_stop()
并打破循环。同时kthread_stop()
将阻塞,直到线程退出。
如果我离开线程完成其循环并自行退出一切正常 喜欢魅力。如果我尝试卸载模块,虽然线程运行整个系统挂起。
do_work_{a,b}()
保证返回。
有人能注意到我错过了什么吗?