Зависание ядра, когда не выполняется tasklet_kill
Я пишу простой код для проверки функции тасклета.
Когда я не выполняю 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 ответ
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_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, что не вызовет паники.