我试图通过在定时器调用的函数中调用 kthread_stop() 来停止内核线程。当我将此模块加载到内核中时,kthread 在定时器中提到的指定时间后启动和停止,但它的在日志中给出一些错误信息。
谁能帮我解决这个问题,因为我是内核线程编程的新手。这是我的代码
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/timer.h>
#include <linux/kthread.h>
#include <linux/sched.h>
MODULE_LICENSE("GPL");
struct task_struct *task;
static struct timer_list my_timer;
int thread_function(void *data) {
printk(KERN_ALERT"IN THREAD FUNCTION");
while(!kthread_should_stop()){
schedule();
}
printk(KERN_ALERT"after schedule\n");
return 1;
}
void my_timer_callback( unsigned long data ){
printk( "my_timer_callback called (%ld).\n", jiffies );
printk(KERN_ALERT"THREAD STOPPED\n");
kthread_stop(task);
}
int init_module( void ){
int ret;
printk("Timer module installing\n");
//my_timer.function, my_timer.data
setup_timer( &my_timer, my_timer_callback, 0 );
printk( "Starting timer to fire in 2000ms (%ld)\n", jiffies );
ret = mod_timer( &my_timer, jiffies + msecs_to_jiffies(2000) );
if (ret) printk("Error in mod_timer\n");
printk(KERN_INFO"-------------------- THREAD START------------------------");
task = kthread_run(thread_function,NULL,"kerneltthread");
printk(KERN_ALERT"Kernel Thread Name: %s\n",task->comm);
return 0;
}
void cleanup_module( void ){
int ret;
ret = del_timer( &my_timer );
if (ret) printk("The timer is still in use...\n");
printk("Timer module uninstalling\n");
return;
}
MODULE_LICENSE("GPL");
这是日志中的输出信息
Aug 5 16:35:31 brao kernel: Timer module installing
Aug 5 16:35:31 brao kernel: Starting timer to fire in 2000ms (4299209850)
Aug 5 16:35:31 brao kernel: -------------------- THREAD START------------------------
Aug 5 16:35:31 brao kernel: Kernel Thread Name: kerneltthread
Aug 5 16:35:31 brao kernel: IN THREAD FUNCTION
Aug 5 16:35:33 brao kernel: my_timer_callback called (4299211856).
Aug 5 16:35:33 brao kernel: THREAD STOPPED
Aug 5 16:35:33 brao kernel: BUG: scheduling while atomic: swapper/3/0/0x10000100
Aug 5 16:35:33 brao kernel: after schedule
最佳答案
Timer 的功能 在 softirq 上下文中执行,因此它不应该休眠。但是您的 my_timer_callback
调用了 kthread_stop
函数,该函数等待直到 kthread 完成,即休眠。
因此,scheduling while atomic
BUG 出现了:函数休眠而它不应该这样做,因为原子上下文。
关于linux - 在 Linux 中使用计时器停止内核线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31831381/