关于linux内核中断处理和内核抢占的两个说明

中断处理不能睡眠和切换:原因随处可以找到,总结起来就是:1.增加了当前任务的不确定性,实时性能得不到保障,毕竟中断上下文是任意进程上下文,这样对那个被中断的进程不公平,我在邮件列表中的原话是:“中断处理占用当前进程的内核栈,因此中断中如果切换了还是可以切换回来的,切换回来时就会到了这个中断发生时的当前进程,但是这样对这个进程不公平,相当于由于特殊原因占据了别人一间屋子,可是你却把门反锁,在里面睡觉而不干正事。当然还会遇到一系列锁的问题。一般的,中断处理函数要尽可能快的完成,因为它是异步的,行为不确定的,本来就没有给它安排执行时间。在中断处理完毕了以后,马上要返回用户空间或者内核空间了,这时一切就确定了,因此必要时就可以切换了”;2.和中断共享中断号的中断会受到影响, 现在的内核设置了INPROGRESS标志. 来了一个同样的中断回有问题;3.中断一旦睡眠,就会以被中断的借用进程的“名义”睡眠,那么它要是直接切换了而没有睡眠在一个队列,何时切换回来就会受到被中断进程的属性的控制,比如该进程是一个很低优先级的进程,那将是噩梦,如果它睡眠了,那么何时唤醒呢?在哪里唤醒呢?这都是问题,睡眠是有原因的,那么条件满足时就会被唤醒,如果无故睡眠,那就别指望总会被唤醒。
关于中断不能睡眠和切换另一个要注意的就是用独立中断栈的情况,系统的同一个cpu都会用同一个中断栈,如果一个中断处理程序睡在了中断栈上,那么它被唤醒切换回来的时候会找不到原来被中断的进程,其实它可能回不来了,中断栈的共享会导致压栈的数据被破坏掉。
内核抢占:注意以下代码:
need_resched:
         movl TI_flags(%ebp), %ecx       # need_resched set ?
         testb $_TIF_NEED_RESCHED, %cl
         jz restore_all
         testl $IF_MASK,EFLAGS(%esp)     # interrupts off (exception path) ?
         jz restore_all
         call preempt_schedule_irq
         jmp need_resched
为何在中断关闭的情况下不能抢占?其实中断关闭意味着程序在临界区或者持有锁或者怕有同步问题和互斥问题才禁用中断的,这种情况下切换进程是危险的。注意testl $IF_MASK,EFLAGS(%esp)监测的是原来的被中断的上下文的压栈数据而不是当前的,因为当前还在中断中呢,没有restore原来的寄存器呢。因此就有可能原来是开中断的,比如异常处理,其实异常处理可以被抢占的,也可以睡眠,毕竟它是确定上下文的,异常肯定是正执行的那个程序的异常,它在执行异常处理时睡了不会不公平,都是自己作的!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值