本文共 1401 字,大约阅读时间需要 4 分钟。
在操作系统的内核设计中,下半部(Bottom Half)与中断处理程序密切相关,但又不直接运行于中断处理程序中。下半部的任务是运行与中断处理程序本身无关但需要异步执行的任务。如何将工作分配到上半部或下半部运行,是内核设计中的重要考量因素。
为了尽量减少中断处理程序的运行时间,下半部任务的设计目标是缩短中断被屏蔽的时间。中断处理程序运行时,会屏蔽所有本地中断,这对系统的响应能力和性能至关重要。由于中断处理程序与其他程序异步执行,因此我们必须尽力缩短中断处理程序的运行时间。
早期的Linux内核主要提供“底半部”(Bottom Half,BH)的机制,通过32个静态创建的底半部组成链表来实现下半部任务的运行。每个底半部在全局范围内同步执行,确保同一时刻只有一个底半部运行。然而,这种机制虽然简单,但灵活性不足,性能也存在瓶颈。
随着内核的发展,任务队列逐渐取代了底半部机制。内核定义了一组任务队列,每个队列包含一个等待调用的函数链表。驱动程序可以将自己的下半部任务注册到合适的队列上,任务将在适当时刻自动运行。
在2.3版本中,内核引入了软中断(Soft Interrupt)和tasklet(Tasklet)两种新的下半部实现机制。软中断是一组静态定义的下半部接口,共有32种,能够在所有处理器上同时运行。tasklet是一种动态创建的下半部实现机制,基于软中断,能够在不同处理器上同时运行,但同一类型的tasklet不能在同一处理器上同时运行。
到2.6版本,内核提供了三种不同的下半部实现机制:软中断、tasklet和工作队列。此外,内核定时器也可以用于将任务推后运行。
软中断的实现与注册过程如下:
softirq_action结构体表示,定义在kernel/softirq.c中。软中断在编译时静态分配,共有32项,数组softirq_vec存储这些结构体。void softirq_handler(struct softirq_action*)。在注冊的软中断索引号处调用处理程序。do_softirq()函数检查和运行待处理的软中断。该函数从软中断位图中提取待处理项,并依次调用相应的处理程序。enum定义软中断类型,索引号从0开始,索引号小的软中断优先运行。open_softirq()函数注册软中断处理程序,例如网络子系统通过net_tx_action和net_rx_action处理发送和接收数据。raise_softirq()函数将软中断设置为挂起状态,待内核下次调用do_softirq()时运行。中断处理程序通常在返回时触发相应的软中断。通过上述机制,软中断能够在系统运行时异步处理任务,确保中断处理程序的高效运行。
转载地址:http://tahfk.baihongyu.com/