【问题标题】:Right way to delete kthread waiting while semaphore will be upped删除 kthread 等待信号量的正确方法将被提升
【发布时间】:2020-03-14 19:22:08
【问题描述】:

我编写了一个使用内核线程和信号量的内核模块。

我从中断处理程序中调用up(...) 信号量函数,然后我的kthread 开始执行。

static int interrupt_handler_thread(void *data)
{
    /* duty cycle */
    while (!kthread_should_stop()) {
        /*
         * If semaphore has been uped in the interrupt, we will
         * acquire it here, else thread will go to sleep.
         */
        if (!down_interruptible(mysem)) {
            /* proccess  gpio interrupt */
            dev_info(dev, "gpio interrupt detected\n"); 
        }
    }

    do_exit(0);

    return 0;
}

信号量和线程被初始化为module_init函数。省略了错误检查。

...
sema_init(mysem, 0);

thread = kthread_create(interrupt_handler_thread,client,"my_int_handler");
wake_up_process(thread);
...

在卸载模块期间,信号量和线程被移除:

/*
* After this call kthread_should_stop() in the thread will return TRUE.
* See https://lwn.net/Articles/118935/
*/
kthread_stop(thread);

/*
* Release the semaphore to return
* from down_interruptible() function
*/
up(mysem);

当我尝试卸载我的模块时,模块冻结在down_interruptible() 函数中的线程中,因为它在中断处理程序中的信号量上升时等待。而且我的代码永远不会从kthread_stop() 返回。

看来,我需要从我的 gpio 禁用中断,手动向上信号量并调用 kthread_stop() 函数。但这是一个潜在的错误,因为在手动增加信号量后,线程开始执行,并且在其占空比之后可以再次down_interruptible()

有人可以帮帮我吗?

PS:我知道this question,但是,这似乎不是我的情况。

【问题讨论】:

  • 来自kthread_stop():将kthread_should_stop 设置为k 返回true,唤醒它,然后等待它退出。而且也很重要:如果你使用这个函数,你的 threadfn 不能自己调用​​ do_exit!
  • @KamilCuk,谢谢,我已经修好了

标签: c linux-kernel semaphore kernel-module


【解决方案1】:

为了正确运行,您的 kthread 应在等待信号量时检查线程的“停止”状态。不幸的是,down 函数没有“可停止”版本。

使用workqueue机制代替kthread。 Works 已经具备您需要的所有功能:

  • 您可以在中断处理程序中添加一个工作 (queue_work),
  • 只能同时运行一项工作,
  • 使用destroy_workqueue,您可以安全地完成所有工作。

实际上,工作队列是使用 kthread 实现的。参见例如kthread_worker_fn函数的实现。

【讨论】:

    猜你喜欢
    • 2013-01-09
    • 2017-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-02
    • 1970-01-01
    • 2021-01-17
    • 1970-01-01
    相关资源
    最近更新 更多