Multithreading 系统在清理内核线程时挂起
我在初始化内核模块时创建了一个内核线程,如下所示:Multithreading 系统在清理内核线程时挂起,multithreading,linux-kernel,Multithreading,Linux Kernel,我在初始化内核模块时创建了一个内核线程,如下所示: static int __init module_init(module) { ... tdata = kmalloc(sizeof(*data)); if (!data) { ... } task = kthread_run(tfunc, tdata, "memtester"); if (!task) { pr_err("memtester: Could no
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)
}
我按如下方式卸载模块:
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)
}
线程函数如下所示:
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)
}
int-tfunc(无效*数据)
{
...
对于(i=0;i<某些_极限;++i){
你工作吗;
/*在这里我需要等待延迟usec*/
对于(j=0;j
在线程函数中,我需要在do\u work\u a()
中执行一些操作,等待delay
usec,然后在do\u work\u b()
中执行其他操作。我的问题是,如果我想在线程运行时删除模块,系统将挂起
我希望在卸载模块并执行kthread\u stop()
时
在某个时刻,线程将执行kthread\u should\u stop()
并中断循环。同时kthread\u stop()
将阻塞,直到线程退出
如果我让线程完成它的循环并自行退出,那么一切都会正常工作
就像一个符咒。如果我尝试卸载模块,当线程运行时,整个系统将挂起
do\u work{a,b}()
保证返回
有人能注意到我遗漏了什么吗?是
do\u work\u a
还是do\u work\u b
执行一些阻塞调用(获取互斥锁,等待事件
等)kthead\u stop()
can。此外,如果使用kthread_stop,则应该。在线程中等待直到调用kthread\u stop
的可能方法请参阅。do\u work\u a
和do\u work\u b
请勿阻塞。实际上他们正在做一些复制品。感谢您的提示。如果延迟<1000,内部for循环中的语句将不会执行一次。因此,尝试移除模块可能会挂起系统,直到外部for循环执行某些限制
迭代。根据do_work_*()
函数的实现方式以及它们在内核中的其他逻辑依赖关系,这可能是一个活锁或死锁。