我编写简单的代码来测试tasklet的功能。
当我不执行tasklet_kill时,内核将在insmod命令使用后挂起。由于没有日志,我不知道会发生什么。
以下是我的代码。
void work_fcn(unsigned long a)
{
printk("this is tasklet work function\n");
}
void tasklet_test(void)
{
struct tasklet_struct task;
tasklet_init(&task, work_fcn, 0);
tasklet_schedule(&task);
//if I don't do the following line, then kernel hang
tasklet_kill(&task);
}
static int __init hello_init(void)
{
tasklet_test();
return 0;
}
module_init(hello_init);
感谢。
答案 0 :(得分:0)
static void tasklet_action_common(struct softirq_action *a,
struct tasklet_head *tl_head,
unsigned int softirq_nr)
{
...
while (list) {
struct tasklet_struct *t = list;
list = list->next;
if (tasklet_trylock(t)) {
if (!atomic_read(&t->count)) {
if (!test_and_clear_bit(TASKLET_STATE_SCHED,
&t->state)) //<===========(1)
BUG();
t->func(t->data);
tasklet_unlock(t);
continue;
}
tasklet_unlock(t);
}
...
}
}
在注释(1)中,它检查tasklet状态是否为TASKLET_STATE_SCHED,如果是,它会panic。
void tasklet_kill(struct tasklet_struct *t)
{
if (in_interrupt())
pr_notice("Attempt to kill tasklet from interrupt\n");
while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
do {
yield();
} while (test_bit(TASKLET_STATE_SCHED, &t->state));
}
tasklet_unlock_wait(t);
clear_bit(TASKLET_STATE_SCHED, &t->state); //<=========(2)
}
EXPORT_SYMBOL(tasklet_kill);
在注释 (2) 中会清除 TASKLET_STATE_SCHED 位,这样就不会恐慌了。