linux中断与下半部

中断:解决cpu和硬件速度差距太大问题,不能让cpu等,也不能让cpu轮询,所以硬件好了给cpu发个信号
硬件(控制器)-中断控制器- cpu (中断控制器在中断线激活(未被屏蔽)才发向cpu)
中断:不需要与cpu时钟同步,异步,随时可以来
异常(缺页,0除):与cpu时钟同步,同步,cpu产生,如系统调用就通过软中断(异常)陷入内核
中断请求线(IRQ)/中断线,一般都屏蔽中断线,很少禁止本地(某cpu)中断
中断处理程序是设备驱动程序(管理设备的内核代码)一部分,驱动程序需注册其中断处理程序
注册:可能会指定(1 处理中断时是否禁止所有其他中断,野蛮行为,不好 2 共享中断线,同一中断线,多个设备,多个程序共享)
卸载驱动时注销中断处理程序,可能会释放(禁用)中断线(共享的情况下还有其他程序)
中断处理程序:返回none(不是我设备发的中断)或handled(是我设备发的中断,处理了),无需重入,一般处理中都会禁掉当前中断线,不会有其他cpu也接到此中断
共享中断举例:依次调用各处理程序,处理程序内判断是否是我的设备(硬件提供支持,如状态寄存器),不是退出(返回none)
中断返回可能用户抢占(need_resched)或内核抢占(need_resched,preempt_count)
中断处理程序:立即执行,尽量快速运行完毕(但至少要通知硬件已收到中断和一些必要的处理)
中断上下文(无进程概念,无阻塞休眠,重新调度这些概念,不能在内调用一些可能阻塞的函数),可能嵌套(中断处理中被其他中断打断,区分其和调度和阻塞的区别)
中断处理程序运行时原先使用被中断进程的内核栈,现在每个cpu有一个中断栈

下半部:合适时机执行,执行可稍后放的工作
举例:网卡在中断里通知硬件并拷贝数据到内存,下半部处理数据。

下半部实现:软中断,tasklet(借助软中断),工作队列
软中断:编译期间静态分配,用到9个(索引号/优先级从0到8,0为高优先级tasklets,5为正常优先级tasklets,理论上限32,),只可能被中断处理程序抢占,但其他cpu也可能运行软中断(甚至同一类型),所以需要同步机制。触发(标记)后才会执行,一般在中断处理程序里标记
软中断执行时机:中断处理程序返回,ksoftirqd内核线程,某些显式检查软中断代码处。
对于时间要求严格,执行频率高的应用,软中断执行最快(性能好),但就是同步考虑太麻烦。
一般很少直接用软中断,都用tasklet,同步考虑少

tasklet:动态注册注销,同一tasklet不能同时在不同cpu上运行(免去很多同步机制),各种中断处理都挂在一个软中断上

ksoftirqd内核线程:处理软中断和tasklet,
问题:中断太多,软中断频繁被触发,且软中断自我触发(标记)导致用户进程饥饿。
1本次软中断处理负责重新触发的软中断,用户进程饥饿
2 重新触发的软中断放到下一次软中断执行时(多为下一次中断返回时),重新触发的软中断饥饿,即便系统空闲也不执行
最终方案:每个cpu一个ksoftirqd内核线程( 如ksoftirqd/0),重新触发的软中断由此内核线程执行(优先级低),抢不过用户线程,在系统空闲时执行

软中断和tasklet都运行在中断上下文中,只不过运行时可响应中断(没有屏蔽中断线或禁止本地中断),但依然不能运行一些可能阻塞的函数等。

工作队列:内核线程和用户线程一样,都是可调度实体,都运行在进程上下文中,只不过它一直运行在内核空间(运行内核代码),且没有内存描述符(借用)
工作队列作为一种可运行阻塞函数的下半部机制,使用内核线程(工作者线程)运行其负责队列中任务。
每个cpu有一缺省工作者线程events/n(如events/0),当然你可以自己创建新的(其他类型的)工作者线程和队列
工作队列开销最大(内核线程和上下文切换),但有睡眠需求也只能用它。

软中断和tasklet:可认为是异步的,中断了其他进程执行。某些时候需要禁止执行(如禁止本地执行)
工作队列:同步的,调度发生才执行,不需要也很难禁止。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值