在Linux中,中断处理程序的处理分为两部分:上半部分和下半部分。
根据我的理解,中断处理程序的下半部分可以用许多方式处理:softirq,tasklet,工作队列和定时器列表。
我想知道Linux内核中的哪些函数处理这些下半部分的调度function。
编辑:我看着softirq和tasklet的halndling,似乎他们都通过__do_softirq处理( http://lxr.linux.no/linux+v2.6.32.58/kernel/softirq.c#L207 )function。 不过,我仍然看到处理程序执行过程中有很多path通过了Linux内核的schedule()函数,然后显示出分歧。 我无法正确解释这些path。
引导你走向这个function的直觉:
未决任务(下半部分)的调度应该由某个事件触发。 内核事件既可以是系统调用,也可以是中断。我认为触发下半部分的事件是中断而不是系统调用。
据我所知,这是中断到来后的步骤:
1.中断到达核心
2.中断处理程序的上半部分运行
3.检查待处理队列,看是否有需要注意的任务。
4.如果有任何未决任务,则执行它
我正在浏览所有OS处理程序的函数列表,并观察到许多处理程序的执行都通过了Linux内核的schedule()函数。 由于这个函数经常被许多中断处理程序调用,所以我认为中断处理程序的下半部分只能从这个函数中调用。
schedule()函数最后调用post_schedule()函数。 我跟踪了这两个函数调用之间的所有函数。 它们之间有许多不同的函数列表,引起了下半部分函数必须位于从schedule()到post_schedule()的path上的怀疑。 然而,内核中不同的MACROS和函数的数量,使得调度器跳转到下半部分的function变得非常困难。
设备驱动程序的中断处理程序的上半部分必须返回IRQ_HANDLED,IRQ_WAKE_THREAD或IRQ_NONE,以向中断子系统表明irq处理与否。 如果返回IRQ_WAKE_THREAD,则中断处理程序的线程下半部分被调度执行。 通常,下半部分比其他正常的内核任务具有更高的优先级。 有关更多详细信息,请参阅https://lwn.net/Articles/302043/