中断处理工作,例如对接收中断进行中断或复位硬件,这些工作都在所有中断被禁止的情况下完成。可以稍后完成的工作推迟到下半部,在合适的情况下执行下半部分中断
当网卡接收流入网络的数据包时,需要通知内核数据包到了,网卡需要立即完成这件事,从而优化网络的吞吐量和传输周期,以避免超时。因此网卡立即发出中断,通知内核这里有最新的数据包。内核通过执行网卡已注册的中断处理程序作出应答。中断开始运行,应答硬件,复制最新的网络数据包到内存,然后读取网卡更多的数据包,这些都是重要的、紧迫的、又与硬件相关的的工作。处理和操作其他数据包的其他工作在随后的下半部分进行。
中断值 称 IRQ 线,中断线
中断上下文 不可睡眠,不可阻塞,中断处理程序栈 一页 每个有自己的。下半部
驱动 request_irq 注册中断处理程序,如果设置 IRQF_DISABLED 在中断程序运行期间不允许其他任何中断同时运行
硬件产生中断 =》中断控制器 =》处理器 =》除非处理器禁止中断,否则关闭中断系统(没设置 IIRQF_DISABLE。同级的其他中断会被屏蔽,设置当前处理器所有中断被屏蔽),跳到中断处理程序入口,每个中断线有唯一入口位置,寄存器值 + 中断号 =》do_irq。应答中断,禁止中断线上的中断传递,调处理程序(share 的调该线上所有的 handler)=》返回
procfs 虚拟文件系统,/proc 这里读写文件都要调内核函数。/proc/interrupts 中
并发:
中断禁止 / 激活 防止其他中断程序并发。禁止一个处理器中断 locaal_irq_discable。禁止一条中断线 disable_irq
锁:防止其他处理器对共享数据并发
下半部
软中断 tasklet 工作队列 内核定时器(tasklet, 内核定时器都是基于软中断)
软中断:编译期间静态分配,注册数组 最多 32 个。标记 / 触发后才会被执行
检查执行点:从硬件中断处返回,在 ksoftirqd 内核线程中,显示调用
软中断不会抢占另一个软中断,唯一可以抢占它的是中断处理程序
但其他软中断(包括同类型)可以在其他处理器上同时执行
do_softirq 遍历数组每个检查执行(一个标记位图一个数组)
现有优先级:hi_softirq timer net_tx net_rx block (新加入) tasklet sched 调度程序等
tasklet 可以动态注册和注销
taasklet_schedule
保存中断,禁止中断。
加入到每个处理器的 tasklet_vec,tasklet_hi_vec 链表表头,触发 tasklet,hi_softirq 软中断,下次 do_softirq 会执行。
恢复中断
tasklet_action
禁止中断,链表 NULL,允许中断(软中断允许中断)
处理链表 tasklet,检查是否被其他处理器处理
ksoftirq 每个处理器协助处理软中断线程
工作队列 交由内核线程执行,进程上下文,允许调度和睡眠
每个 CPU 每个类有一个个工作队列线程(默认只有一类:event),cpu_workqueue_struct
每类有一个个 workqueue_struct
怎么选?
有睡眠 =》工作队列。
否则 =》tasklet。
对性能要求极高 软中断。需要自己保证同类型不能同时执行
时钟
时钟中断频率 HZ 内核 1000HZ 1ms 用户空间 100HZ
jiffies 1s 内中断次数 =HZ 回绕到 0
实时时钟(设备)初始化 xtime 实际时间 / 墙上时间
时钟中断处理程序 update_process_time 更新 rusage;执行定时器 timer
timer schedule_timeout 按照超时时间把任务分为 5 组
延迟执行 udeley,nndelay 这种少于 ms 的用执行循环次数控制
中断处理过程中发生其它中断