Linux内核的一些知识。

一、中断处理函数里面为何不可以进行sleep,信号量操做linux

中断处理函数里面不可以进行sleep有比较多的缘由,有如下几个方面:tcp

  • 临界区确定是不能进行sleep的,这样子会致使系统瘫痪。
  • 中断上下文没有相应的task_struct,由于 linux进程内核调度是以task_struct为单位的,因此若是进行sleep的话将没法进行恢复。但这个不是主要缘由,由于 solaris的中断上下文有相应的调度描述符IST。(因此这里来料了,以前有同事说tcp三次握手完成的时候,这个链接属于哪一个pid,在Linux上表现为空,此时不知道谁持有这个链接,多是由于 没有上下文,但若是在solaris这样的环境可能就属于中断调试 IST的了)
  • 为了简单可控,若是容许中断处理函数中进行sleep的话,可能当前调度优先级比较低的话,那么它很难被恢复过来,另外,栈空间溢出也是个问题,由于目前中断栈只有4k。
  • 内核设计缘由:内核设计的诸多因素使得这个没法实现,好比目前的中断线是每一个CPU一个,a  sleep ->schedule b -> b sleep -> a(i don't know where my stack is)

 

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

相关文章
相关标签/搜索