zylthinking
发表于 2011-09-26 15:09
回复asuka2001
关中断跟禁止抢占之间没有关系么?
关掉中断之后,时钟肯定也关了,也就调度相关的代码 ...
vonnyfly 发表于 2011-09-26 15:06 http://bbs.chinaunix.net/images/common/back.gif
为什么3不可能??
asuka2001
发表于 2011-09-26 15:12
刚刚回复的时候没回复完,那里是:spin_lock_irqsave本身应该禁止了抢占吧,毕竟获取了自旋锁!
至于关中断和抢占,好象没啥联系,preempt_count里只有针对软中断,硬中断,和关闭抢占的计数器。
抢占的时机不仅仅和中断有关,比如解除自旋锁的时候也会恢复抢占,并且可能导致重新调度吧???
SharkBones
发表于 2011-09-26 15:19
回复 6# vonnyfly
linux的实时进程有两种调度策略,SCHED_FIFO和SCHED_RR,SCHED_FIFO是简单的队列调度,并且没有timeslice的限制,谁先来谁运行,除非是阻塞或者主动yield,否者将一直占用CPU,即使关中断也不能阻止优先级高的进程被调度运行。
SharkBones
发表于 2011-09-26 15:28
回复 6# vonnyfly
还有,中断是随时产生的,因此在中断服务程序被调用的时候,不能依赖于任何进程的状态,也就不能调用schedule()等与进程运行环境有关的函数,第3点中的驱动程序中调用schedule应该不成立吧。
local_irq_save只是关闭了当前CPU上的中断,但并不能阻止其他CPU上的进行进程调度,就可能调度到某个进程,这个进程也要访问同样的临界区。
xs3c
发表于 2011-09-26 16:13
spin_lock_irqsave本身应该禁止了抢占吧,毕竟获取了自旋锁!
至于关中断和抢占,好象没啥联系,pre ...
asuka2001 发表于 2011-09-26 14:55 http://bbs.chinaunix.net/images/common/back.gif
spin_lock_irqsave 应该也关中断吧。
zonewone
发表于 2011-09-27 13:27
为什么3不可能??
zylthinking 发表于 2011-09-26 15:09 http://bbs.chinaunix.net/images/common/back.gif
拿了锁又去主动调用调度是代码bug
kouu
发表于 2011-09-27 16:23
回复 1# vonnyfly
假设有这么个情况:
1、CPU-1在进程A的上下文调用了spin_lock_irqsave;
2、CPU-2调用wake_up_process唤醒了CPU-1上的进程B,由于进程B的优先级高于进程A,进程A的TIF_NEED_RESCHED标记被设置。(CPU-2还会用IPI通知CPU-1进行resched,但是CPU-1禁用了中断而不会响应);
3、CPU-1调用了某某函数,这个函数包含了preempt_disable和preempt_enable(没有规定关中断的情况下不能调用这样的函数吧~);
那么,如果spin_lock_irqsave没有preempt_disable,第3步中的preempt_enable将触发preempt_check_resched,从而让进程B抢占掉进程A。
鸟菜小
发表于 2011-09-27 20:32
不光从中断返回,preempt_enable()也是一个潜在的主动调度的测试点。spin_lock_irqsave只有关了抢占,才能保证在临界区成对出现的preempt_disable()/preempt_enable()不会造成伤害。不然这种代码就不能放在临界区中了。
chishanmingshen
发表于 2011-10-02 19:28
自旋锁可以防止其它处理器抢占本处理器,但是如果本处理器不关本地中断,还是会被本处理的其它进程抢占.
若其它进程也申请自旋锁,就会导致自旋锁的死锁.
tempname2
发表于 2011-10-03 10:52
回复 17# kouu
有道理,但实际上代码(3.0.4)里面,preempt_enable检查到有调度需求后用调用preempt_schedule():/*
* If there is a non-zero preempt_count or interrupts are disabled,
* we do not want to preempt the current task. Just return..
*/
if (likely(ti->preempt_count || irqs_disabled()))
return;
中断关闭会被照顾。