我试图了解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的动作函数运行之前,启用了中断。
是否意味着动作函数(延迟函数)在进程上下文中运行,或者我们还没有完全从中断返回(我们在驱动程序中断处理程序之后就已经出路了),因此延迟函数在中断上下文中运行?
通常,从驱动程序的中断处理程序(在禁用中断的情况下运行)调用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);
}
答案 0 :(得分:1)
首先,答案取决于Linux版本。 tasklet 和其他是一个内部Linux API,可以在不同版本之间进行更改。
是否意味着动作函数(延迟函数)在进程上下文中运行,或者我们还没有完全从中断返回(我们在驱动程序中断处理程序之后就已经出路了)因此延迟函数在中断上下文中运行?
中断上下文是特殊的,它在被中断任务的内存空间/上下文中运行。 tasklet 在内核进程中运行,没有映射用户内存;但它处于超级模式。您可以在此处调用更多内核函数,因为内核对象将代表内核进程而不是某些随机用户进程进行分配。如何运行 tasklet 可能取决于Linux版本,但肯定会发生上下文切换。通常,内核进程标记为 runnable ,并且中断返回。当然, tasklet (内核进程)通常可以中断。
通常,从驱动程序的中断处理程序(在禁用中断的情况下运行)调用tasklet_schedule,但为什么还需要再次禁用中断?
中断可以预先设置/优先级。即,更高级别的中断可能会中断另一个中断。此外,可以从更多调用tasklet_schedule()
而不是中断上下文。即,一些kickstart初始化或一些这样的?
这个问题似乎是代码批评?有可能使tasklet_schedule()
假定禁用中断。但是,它容易出错,保存中断的代码很少。我认为要么是可能的,所以为什么是一个棘手的问题。