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_*()
函数的实现方式以及它们在内核中的其他逻辑依赖关系,这可能是一个活锁或死锁。