0

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

谢谢。

4

1 回答 1

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,如果是,它会恐慌。

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位,不会恐慌。

于 2021-02-22T12:27:03.687 回答