暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Linux中的中断处理机制(四)

术道经纬 2019-11-04
145

为了避免嵌套带来的不确定性,现在的Linux系统通常选择在中断函数处理期间关闭中断。

可是,如果关中断的时间长了,势必会影响对其他IRQ的响应,时间短了又处理不完。为此,上文提到的第二级的中断处理又被分成了两个部分,一个是俗称的“顶半部”(top half),在此期间,中断关闭,软件主要完成对硬件中断的应答,需要快速执行完毕。另一个与之对应的就是底半部”(bottom half) ,在底半部中,中断打开,内核继续完成在顶半部中未完成的中断处理。

底半部代表了中断处理中被延后(deferred)执行的部分,目前Linux支持的底半部机制有3种:softirq, tasklet和work queue。其中tasklet的实现是建立在softirq之上的,两者都是由内核2.3版本引入的,而作为后起之秀的work queue,则是伴随2.5版本首次亮相的。从概念匹配的角度,我们有时会把顶半部对应地称为"hardirq"。

软中断

softirq,有时会被人们称作是"software interrupt"。在Linux中,早期用来实现system call的"int 0x80",以及用于异步通信的信号(signal)机制常常也被叫做software interrupt。为了区分,中文里会把它们分别叫做“软中断”和“软件中断”啥的,弄的人一头雾水。


其实啊,把"int 0x80"叫做software interrupt来自于Intel的手册,在具体的实现中,它确实有和硬件中断类似的处理流程,都走IDT表什么的,但它的作用是由ring 0切换到特权级更高的ring 3,对应从操作系统的用户态切换到内核态。现在这种实现系统调用的方式已经被SYSENTER/SYSCALL指令取代,基本不再使用了。


而signal机制呢,算是从软件层面对硬件中断的一种模拟,它的效果和硬件中断是差不多的,但其实现方式和硬件中断的处理流程可以说是完全没有关系。至于softirq,则本身就是属于硬件中断处理的一部分,只是它处理的是相对不那么紧急,显得"soft"一些的部分。signal和softirq在内核的实现中有很多相似之处,你将在本文后面的叙述中慢慢看到。

softirq的安装

中断的来源很多,所以softirq的种类也不少。内核的限制是不能超过32个,目前实际用到的由9个,其中两个用来实现tasklet(HI_SOFTIRQ和TASKLET_SOFTIRQ),两个用于网络的发送和接收操作(NET_TX_SOFTIRQ和NET_RX_SOFTIRQ),一个用于调度器(SCHED_SOFTIRQ),实现SMP系统上周期性的负载均衡。在启用高分辨率定时器时,还需要一个HRTIMER_SOFTIRQ。


为了有效地管理不同的softirq中断源,Linux采用的是一个名为softirq_vec[]的数组,数组的大小由NR_SOFTIRQS 表示,这是在编译时就确定了的,不能在系统运行过程中动态添加。为了便于多核的并行处理,它还被设计成了per-cpu类型的数组,也就是每个processor对应一个softirq_vec[]数组。每个数组元素代表一种softirq的种类,而数组里存放的内容则是其各自对应的执行函数。

struct softirq_action
{
void (*action)(struct softirq_action *);};struct softirq_action softirq_vec[NR_SOFTIRQS];
文章转载自术道经纬,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论