Kernel Mechanisms (核心机制)
本章描述了 Linux 核心需要提供的一些一般的任务和机制,让核心的其余部分可以有效地工作。
11.1 Bottom Half Handling
通常在核心中会有这样的时候:你不希望执行工作。一个好例子是在中断处理的过程中。当引发了中断,处理器停止它正在执行的工作,操作系统把中断传递到适当的设备驱动程序。设备驱动程序不应该花费太多时间来处理中断,因为在这段时间,系统中的其他东西都不能运行。通常一些工作可以在稍后的时候进行。 Linux 发明了 boffom half 处理程序,这样设备驱动程序和 Linux 核心的其它部分可以把可以稍后作的工作排队。图 11.1 显示了同 bottom half 处理相关的核心数据结构。有多达 32 个不同的 bottom half 处理程序: bh_base 是一个指针的向量表,指向核心的每一个 bottom half 处理例程, bh_active 和 bh_mask 按照安装和激活了哪些处理程序设置它们的位。如果 bh_mask 的位 N 设置,则 bh_base 中的第 N 个元素会包含一个 bottom half 例程的地址。如果 bh_active 的第 N 位设置,那么一旦调度程序认为合理,就会调用第 N 位的 bottom half 处理程序。这些索引是静态定义的: timer bottom half 处理器优先级最高(索引 0 ), console bottom half 处理程序优先级次之( index 1 )等等。通常 bottom half 处理例程会有和它关联的任务列表。例如这个 immediate buttom half handler 通过包含需要立即执行的任务的 immediate 任务队列( tq_immediate )来工作。
参见 include/linux/interrupt.h
核心的一些 bottom half 处理程序和设备有关,但是其它的是更一般的:
TIMER 这个处理程序在每一次系统定时时钟中断被标记成为激活,用来驱动核心的时钟队列机制
CONSOLE 这个处理程序用来处理控制台消息
TQUEUE 这个处理程序用来处理 TTY 消息
NET 这个处理程序用来处理通用的网络处理
IMMEDIATE 通用的处理程序,一些设备驱动程序用来排列稍后进行的工作
设备驱动程序或者核心的其它部分,需要调度稍后进行的工作的时候,它就在适当的系统队列中增加这个工作,例如时钟队列,然后就发送信号到核心,一些 bottom half 处理需要进行。它通过设置 bh_active 中的合适的位来做到这点。如果驱动程序在 immediate 队列排列了一些东西并希望 immediate bottom half 处理程序会运行并处理它的时候就设置第 8 位。每一次系统调用的最后,把控制权返回调用程序之前都检查 bh_active 的位掩码。如果有任意位被设置,相应的激活的 bottom half 处理例程就被调用。首先检查位 0 ,然后 1 直到位 31 。调用每一个 bottom half 处理例程调用的时候就清除 bh_active 中相应的位。 Bh_active 是易变的:它只在调用调度程序之间有意义,通过设置它,当没有需要作的工作的时候可以不调用相应的 bottom half 处理程序。
Kernel/softirq.c do_bottom_half()
11.2 Task Queues (任务队列)
任务队列是核心用来把工作推迟到以后的方法。 Linux 由一个通用的机制,把工作排列在队列中并在稍后的时间进行处理。任务队列通常和 bottom half 处理程序一起使用:当 timer bottom half 处理程序运行的时候处理计时器任务队列。任务队列是一个简单的数据结构,参见图 11.2 ,包括一个 tq_struct 数据结构的单链表,每一个包括例程的指针和指向一些数据的指针。