- 论坛徽章:
- 0
|
本帖最后由 MagicBoy2010 于 2012-03-01 22:32 编辑
看MagicBoy2010 兄书想到一个问题(以前怎么就没想到呢):
down_interruptible
__down_interruptible
__down_common (当然这个内联,和问题无关)
其中自旋锁顺序为:
spin_lock_irqsave(&sem->lock, flags); 1
……
spin_unlock_irq(&sem->lock); 2
timeout = schedule_timeout(timeout);
spin_lock_irq(&sem->lock); 3
……
spin_unlock_irqrestore(&sem->lock, flags); 4
1234处加锁解锁不对称,会不会有问题?
比如有2个内核线程争用信号量,一个调用顺序如上,另一个依次为5678.那调用顺序会不会变成12563478,导致1中保存的中断开关状态(可能关着),变为了5中保存的中断状态(必然开着)?
=================================================================================================
在SMP系统中,如果两个内核线程在不同的处理器上争用信号量,就不会出现你说的中断状态改变的问题。所以我想你更关心的是UP系统,在UP系统上,你所说的调用顺序我觉得是有可能的,2处spin_unlock_irq实际上演化成local_irq_enable和preempt_enable,2处接下来就会有一个调度点,所以运行另一个线程B是完全可能的,B如果调用down_interruptible,就进入了你所说的调用顺序,因此5将保持一个打开的中断,4退出时中断是关的(如你假设的那样),但是8退出时中断是打开的。不过我的理解是,它不会对系统造成什么影响,因为你假设的前提是1之前中断是关闭的,而中断关闭的情形无非是1.hardirq阶段,2. UP系统中的互斥保护,情形1显然不可能,hardirq阶段你不应该调用down,至于2嘛,down调用的本身就是用来实现互斥,更没有理由在其调用前关掉系统中断,所以从这个角度,我感觉1和4处直接用spin_lock_irq貌似更合理点,你觉得呢?
其实这里还有一个很有趣的问题是在schedule_timeout函数中,__down_common会将当前进程状态设置为TASK_INTERRUPTIBLE,然后会调用schedule,但是在schedule之前,抢占是有可能,那么current会被移除运行队列吗?
|
|