一、中断处理函数里面为何不可以进行sleep,信号量操做linux
中断处理函数里面不可以进行sleep有比较多的缘由,有如下几个方面:tcp
tasklet应用于异常后半部分的处理,优先级比前半部分要低,它在一些检查点被触发调用,一般tasklet也在中断上下文中被处理,因此和中断处理程序同样,不能sleep也不能去调度,不能使用信号量。函数
a.若在中断中schedule tasklet, 中断结束后当即运行;
b.若CPU忙,在不在这次中断后当即运行;
c.不在中断中shedule tasklet;
d.有软或硬中断在运行;
e.从系统调用中返回;(仅当process闲时)
f.从异常中返回;
g.调度程序调度。(ksoftirqd运行时,此时CPU闲)
tasklet通常经过wake_up函数来唤醒等待队列里面的进程,每一个驱动均可以自定义一个等待队列DECLARE_WAITQUEUE,进程通常在写设备的时候调用 wait_event_xxx的方式陷入等待。工具
硬中断触发时,CPU会将中断判断,此时CPU处于临界区。CPU退出临界区后能够开中断spa
咱们可使用vmstat 来查看压力状况下的内存状况,cpu在系统/用户态的耗时,进程/任务切换的次数等,vmstat 是个好工具。翻译
但用vmstat的时候,发现 中断次数比进程/任务切换的次数还要多,因而怀疑软件中断是否是不计入中断计数的。因而去查阅linux/arch/arm/kernel下的熟悉的entry-armv.s,发现软件中断的向量跟irq的不同,处理函数也不同,do_IRQ是会进行计数的,而arm_syscall不会进行计数,所以vmstat上面显示的进程/任务切换的次数比中断次数还要多。设计
从内核态到用户态时,须要切换页表目录,寄器,以及权限寄存器CPSR。调试
多核心的CPU中,每一个核心应该都要有本身的TLB,这样子MMU在进行翻译的时候才不会混淆,固然,多核心cpu在进行进程切换的时候状况可能更加复杂一点,还涉及到cache相关的问题,好比cache是以VA(虚拟地址)仍是PA(物理地址)做为索引的。目前CPU核心看到的地址都是虚拟地址,而Cache,MMU,DMA等设备看到的都是物理地址。code