13646阅读 17评论2012-10-09 MagicBoy2010
分类:LINUX
是的 因为关中断只是关掉本地CPU的中断,多个CPU的情况下,别的CPU仍然可以处理中断,这时就有可能会出现问题
<div class="quote"><span class="q"><b>lmnos</b>: 是的 因为关中断只是关掉本地CPU的中断,多个CPU的情况下,别的CPU仍然可以处理中断,这时就有可能会出现问题.....</span></div>SMP很好理解,关键是UP上<img src="/image/face/3.gif" >
<div class="quote"><span class="q"><b>MagicBoy2010</b>: SMP很好理解,关键是UP上<img src="/image/face/3.gif" >.....</span></div>是的 <img src="/image/face/3.gif" >您可以看一下我的spinlock实现的好不好 我的博文:lmos的一些框架性代码,谢谢
<div class="quote"><span class="q"><b>lmnos</b>: 是的<img src="/image/face/3.gif" >您可以看一下我的spinlock实现的好不好 我的博文:lmos的一些框架性代码,谢谢.....</span></div>没看出什么问题。x86_spin_lock_cli(),你的OS支持抢占吗?另外,为什么不使用cmpxchg指令呢?
<div class="quote"><span class="q"><b>MagicBoy2010</b>: 没看出什么问题。x86_spin_lock_cli(),你的OS支持抢占吗?另外,为什么不使用cmpxchg指令呢?.....</span></div>是的,原生支持内核级抢占,cmpxchg这条指令好像是较新的CPU才有呢。为了支持老处理器。谢谢啊<img src="/image/face/3.gif" ><img src="/image/face/3.gif" >
谢谢,陈老师解答。<br /> 但是还有一个问题,即便是在UP系统上,关闭了中断,那么还有异常~<br /> 对于ARM来说,关闭中断的最底层是关闭了cpsr上的I(Linux不使用F),那么如果在spinlock中出现了其他“异常”,会不会导致调度?<br /> 所以还需要确定的是除外部引发的中断,其他的异常有没有可能引发调度。<br /> 这点我还不是很确定,必须RTFSC
<div class="quote"><span class="q"><b>tekkamanninja</b>: 谢谢,陈老师解答。<br /> 但是还有一个问题,即便是在UP系统上,关闭了中断,那么还有异常~<br /> 对于ARM来说,关闭中断的最底层是关闭了cpsr上的I(Linux不使用F),那么.....</span></div>ARM我不是很了解,x86的情况下,内核态的代码,能产生异常吗,处理异常应该不会发生调度吧,我也不太了解。
<div class="quote"><span class="q"><b>lmnos</b>: ARM我不是很了解,x86的情况下,内核态的代码,能产生异常吗,处理异常应该不会发生调度吧,我也不太了解。.....</span></div>我也不太确定,所以请教下陈老师~~~~~<br /> RTFSCing~~~
<div class="quote"><span class="q"><b>tekkamanninja</b>: 我也不太确定,所以请教下陈老师~~~~~<br /> RTFSCing~~~.....</span></div>既然说到异常,我也有个问题想请教陈老师,x86下,一个进程的内核态堆栈溢出的化,怎么办,有什么办法可以检测,如果检测到该怎么办,这个问题我一直都没想明白。谢谢了
<div class="quote"><span class="q"><b>lmnos</b>: 既然说到异常,我也有个问题想请教陈老师,x86下,一个进程的内核态堆栈溢出的化,怎么办,有什么办法可以检测,如果检测到该怎么办,这个问题我一直都没想明白.....</span></div>这个可以参考现在内核代码中中断处理框架中防止中断栈溢出的方法,相对中断嵌套导致的中断栈溢出,普通进程的内核态堆栈溢出概率极低
<div class="quote"><span class="q"><b>tekkamanninja</b>: 我也不太确定,所以请教下陈老师~~~~~<br /> RTFSCing~~~.....</span></div>可以看看最新的代码,ret_from_exception中在中断关闭的情形下如何处理。我个人觉得异常在发生时和进程关系密切,比如缺页异常,没有理由在这种情形下做一次进程切换,但是这个还是仔细看看内核代码比较稳妥,应该是在arch/x86/kernel/entry.s中。。。
<div class="quote"><span class="q"><b>MagicBoy2010</b>: 这个可以参考现在内核代码中中断处理框架中防止中断栈溢出的方法,相对中断嵌套导致的中断栈溢出,普通进程的内核态堆栈溢出概率极低.....</span></div>但确实没有什么硬性措施,如果这种情况一旦发生的化,那将是灾难性的后果。在进程的用户态下,只要控制好映射用户态堆栈的页表,就可以硬性的扩充用户态堆栈的大小或者检测用户态堆栈是否溢出。但是内核态堆栈则无法这样做,只能靠内核开发者良好的编程行为,我不知道,我在一内核模块的函数中写这样的语句,比如<br /> knrl_mode()<br /> {<br /> ...... <br /> char buf[8192];<br /> ......<br /> }<br /> 会产生什么情况。
<div class="quote"><span class="q"><b>tekkamanninja</b>: 我也不太确定,所以请教下陈老师~~~~~<br /> RTFSCing~~~.....</span></div>刚看了一下3.4.3的内核代码, 在内核路径中,如果在中断关闭的情形下发生异常,异常返回时应是不会发生进程切换(都是在preempt enable的情况下)arch/x86/kernel/entry_32.S:<br /> <br /> ret_from_exception:<br /> ...<br /> cmpl $USER_RPL, %eax<br /> jb resume_kernel<br /> ...<br /> ENTRY(resume_kernel)<br /> ...<br /> need_resched: /*我们假设在关闭中断时没有关闭内核抢占*/<br /> ..
Hi 博主:<br /> 从这篇博文中,其一的论点就是“spin_lock_irqsave保护的临界区内容是禁止本地CPU的进程调度的”。这个问题困扰了我很久,我也在网上搜了很多,总之大家的众说风云,我也在我们开发的双核安卓手机上面做过实验,但无法设计出来一个很好的实验,总之还是无法证明此问题。<br /> 对于这个问题,博主是否有进一步的论点能够支持此论点,我想进一步和你探讨一下,谢谢
spin_lock_irqsave内含preempt_disable和local_irq_disable,在本地CPU中断关闭的情形下你能想到的进程调度的情形是什么呢?不太明白你困惑的原因...
假如我设计一个极限情况,如果一个进程被spin锁住的进程,占用CPU的时间超过了0.95 s,如果不进行进程调度的话是会饿死普通进程吧?<br />我觉得进程调度应该是一个绝对的方法,一个进程时间片用完了就要换到低优先级的进程以保证其他进程不被饿死,阻止了中断和抢占,但应该并不能进程schedule()的发生;<br />如果spin_lock_irqsave能够阻止进程调度的话,那么为何只说阻止了中断和抢占,直接说阻止了进程调度不是更easy一些?
如果一个进程时间片用完当然会导致进程的切换,但是进程时间片需要时钟中断去更新,local_irq_disable实际上阻止了这种可能性。抢占意味着当中断发生时,一个进程被投入到当前cpu的运行队列,调度器需要检查它与被中断进程的优先级以确定是否要抢占它。可以简单做个试验,你写一个内核模块,在模块(test.ko)的初始化函数中这样做:<br />spin_lock_irqsave(...);<br />unsigned long j = jiffies + 300 * HZ;<br />while (time_before (jiffies, j));<br />spin_unlock_irqsave(...);<br /><br />在多处理系统中你可以将insmod进程绑定到cpu 0上:<br />#taskset 0x000000001 insmod test.ko<br /><br />这样你应该有机会从其他cpu上去察看cpu0上task switch发生的次数(/proc?),在cpu0上insmod进程在模块的初始化函数中在spin_lock_irqsave下面忙等待5分钟,这个时间远大于一个进程所拥有的时间