不执行tasklet_kill

时间:2015-10-11 11:50:11

标签: linux-kernel tasklet

我编写简单的代码来测试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);

感谢。

1 个答案:

答案 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 位,这样就不会恐慌了。