判断当前上下文类型
每个cpu有一个per-cpu类型的int变量__preempt_count,它描述了当前抢占信息。
该变量作用划分如下:
* PREEMPT_MASK: 0x000000ff
* SOFTIRQ_MASK: 0x0000ff00
* HARDIRQ_MASK: 0x000f0000
* NMI_MASK: 0x00100000
* PREEMPT_NEED_RESCHED: 0x80000000
相应字段的值用来表示当前的嵌套次数。
在函数中可以通过下面的宏来判断当时与中断、抢占相关的状态:
/*
* Are we doing bottom half or hardware interrupt processing?
* Are we in a softirq context? Interrupt context?
* in_softirq - Are we currently processing softirq or have bh disabled?
* in_serving_softirq - Are we currently processing softirq?
*/
#define in_irq() (hardirq_count())
#define in_softirq() (softirq_count())
#define in_interrupt() (irq_count())
#define in_serving_softirq() (softirq_count() & SOFTIRQ_OFFSET)
它们的判断是通过读取__preempt_count的值,然后通过掩码方式取出相应部分的值。 这些宏如果为0,表示不处在相应状态;如果不为0则表示位于相应状态,并且其值代表了嵌套次数。
中断Bottom Half推迟
bottom half推迟到下列几种情况:
- 推迟到 top half 执行完毕:softirq机制、tasklet机制
- 推迟到某个指定时间片之后执行:timer类型的softirq
- 推迟到某个内核线程被调度的时候执行:中断线程化处理(threaded irq handler)、workqueue机制
softirq/tasklet执行时机
中断处理将不那么紧急的事情推迟到 bottom half 中执行,具体如何推迟执行又分成两种:
- 有具体时间要求的
- 没有具体时间要求的
没有具体时间要求的又可以分成两种:
- 越快越好型:除了中断 top half 可以抢占其执行外,其他的进程上下文(无论该进程优先级有多高)是无法影响其执行的。softirq、tasklet属于这类。
- 随遇而安型:其执行依赖于系统的调度器。threaded irq handler、workqueue机制属于这类。
softirq在下述情况下可能被得到处理:
- 中断返回用户空间时
- 中断返回内核态的进程上下文时。这种情况发生在当进程调用
local_bh_disable/local_bh_enable进入临界区时发生了硬件中断并pending了softirq,但是此硬件中断返回时候不会处理softirq,因为此时依旧是bh disable的,当它返回到临界区中并调用了local_bh_enable时,在local_bh_enable中可能会处理。 - 系统非常繁忙,不断地产生中断、raise softirq,因为 Bottom Half 优先级特别高,导致进程无法调度。这种情况下,softirq会推迟到
ksoftirqd线程中执行。
softirq代码分析
注册softirq
softirq的类型是

本文详细分析了Linux内核中的softirq机制,包括判断当前上下文类型、中断Bottom Half的推迟策略、softirq与tasklet的执行时机以及softirq的注册、触发和处理过程。软中断在中断返回用户空间、中断返回内核态和系统繁忙时可能被处理,其处理时间受到限制以确保系统的实时性。softirq的注册通过`register_SOFTIRQ.Handler`完成,触发通过`raise_softirq`或`do_IRQ`,处理则在满足特定条件时由内核自动进行。
最低0.47元/天 解锁文章
539

被折叠的 条评论
为什么被折叠?



