Tasklet的动作功能是否在中断时运行?

时间:2016-08-05 18:48:27

标签: linux-kernel arm linux-device-driver

我试图了解Tasklet的action函数(已在tasklet_init中设置)运行的上下文?

static void tasklet_action(struct softirq_action *a)
{

    struct tasklet_struct *list;

    local_irq_disable();
    list = __this_cpu_read(tasklet_vec.head);
    __this_cpu_write(tasklet_vec.head, NULL);
    __this_cpu_write(tasklet_vec.tail, this_cpu_ptr(&tasklet_vec.head));
    local_irq_enable();

    while (list) {
    if (tasklet_trylock(t)) {
        t->func(t->data);
        tasklet_unlock(t);
    }
    ...
    ...
    ...
}

上面的函数表明,在Tasklet的动作函数运行之前,启用了中断。

  1. 是否意味着动作函数(延迟函数)在进程上下文中运行,或者我们还没有完全从中断返回(我们在驱动程序中断处理程序之后就已经出路了),因此延迟函数在中断上下文中运行?

  2. 通常,从驱动程序的中断处理程序(在禁用中断的情况下运行)调用tasklet_schedule,但为什么还需要再次禁用中断?

    void __tasklet_schedule(struct tasklet_struct *t)
    {
    
        unsigned long flags;
    
        local_irq_save(flags);---> Interrupts is disabled again ?
        t->next = NULL;
        *__this_cpu_read(tasklet_vec.tail) = t;
        __this_cpu_write(tasklet_vec.tail, &(t->next));
        raise_softirq_irqoff(TASKLET_SOFTIRQ);
        local_irq_restore(flags);
    
     }
    

1 个答案:

答案 0 :(得分:1)

首先,答案取决于Linux版本。 tasklet 和其他是一个内部Linux API,可以在不同版本之间进行更改。

  

是否意味着动作函数(延迟函数)在进程上下文中运行,或者我们还没有完全从中断返回(我们在驱动程序中断处理程序之后就已经出路了)因此延迟函数在中断上下文中运行?

中断上下文是特殊的,它在被中断任务的内存空间/上下文中运行。 tasklet 在内核进程中运行,没有映射用户内存;但它处于超级模式。您可以在此处调用更多内核函数,因为内核对象将代表内核进程而不是某些随机用户进程进行分配。如何运行 tasklet 可能取决于Linux版本,但肯定会发生上下文切换。通常,内核进程标记为 runnable ,并且中断返回。当然, tasklet (内核进程)通常可以中断。

  

通常,从驱动程序的中断处理程序(在禁用中断的情况下运行)调用tasklet_schedule,但为什么还需要再次禁用中断?

中断可以预先设置/优先级。即,更高级别的中断可能会中断另一个中断。此外,可以从更多调用tasklet_schedule()而不是中断上下文。即,一些kickstart初始化或一些这样的?

这个问题似乎是代码批评?有可能使tasklet_schedule()假定禁用中断。但是,它容易出错,保存中断的代码很少。我认为要么是可能的,所以为什么是一个棘手的问题。