珠海专业机械网站建设,手机百度建设网站,nike diy定制网站,电商培训大概多少学费接前一篇文章#xff1a;Linux内核与驱动面试经典“小”问题集锦#xff08;2#xff09; 问题4
问#xff1a;既然spin_lock可以在进程上下文和中断上下文中使用#xff0c;那么一旦进入中断#xff0c;被自旋住#xff0c;那么CPU岂不是被死锁住了#xff1f;
备注…接前一篇文章Linux内核与驱动面试经典“小”问题集锦2 问题4
问既然spin_lock可以在进程上下文和中断上下文中使用那么一旦进入中断被自旋住那么CPU岂不是被死锁住了
备注这个问题是笔者当年参加比特大陆面试的时候被问到的。当时他们先是问了自旋锁和信号量我答上来了。正在心中窃喜之际面试官突然追问了这个问题。由于此前遇到过的此类面试题都是只问到自旋锁与信号量的区别就可以了并没有如此深入因此当时就懵住了。说明对于自旋锁的掌握还是不够透彻。
答
自旋锁主要针对SMP或单CPU但内核可抢占的情况对于单CPU且内核不支持抢占的系统自旋锁退化为空操作。在单CPU且内核可抢占的系统中自旋锁持有期间内核的抢占将被禁止。由于内核可抢占的单CPU系统的行为实际上类似于SMP系统因此在这样的单CPU系统中使用自旋锁仍十分必要。另外在多核SMP的系统中任何一个核拿到了自旋锁该核上的抢占调度也暂时禁止了但是没有禁止另外一个核的抢占调度。
在多核编程的时候如果进程和中断访问同一片临界资源则一般需要在进程上下文中调用spin_lock_irqsave()/spin_unlock_irqrestore()在中断上下文中调用spin_lock()/spin_unlock()。这样在CPU0上无论是进程上下文还是中断上下文获得了自旋锁此后如果CPU1上不论是进程上下文还是中断上下文想要获得同一自旋锁都必须忙等待这避免了一切核间并发的可能性。
额外
由此引申出一个进阶问题。
问在使用自旋锁的时候有哪些注意事项
答
驱动工程师应谨慎使用自旋锁在使用过程中要特别注意如下几个问题
1自旋锁实际上是忙等待锁当锁不可用时CPU一直循环执行“测试并设置”该锁直到其可用而取得该锁。CPU在等待自旋锁时不做任何有用的工作仅仅是等待。因此只有在占用锁的时间极短的情况下使用自旋锁才是合理的。当临界区很大或者有共享设备的时候需要较长时间占用锁使用自旋锁会降低系统的性能。
2自旋锁可能导致系统死锁。引发这个问题最常见的情况是递归使用一个自旋锁即如果一个已经拥有某个自旋锁的CPU想第二次获得该锁则此CPU将死锁。也就是说自旋锁不可递归。
3在自旋锁锁定期间不能调用可能引起进程调度的函数。如果进程获得自旋锁之后再阻塞如调用copy_from_user、kmalloc、msleep等函数则可能导致内核的崩溃引发内核panic。
4在单核情况下编程的时候也应该认为自己是多核的。比如在单CPU的情况下若中断和进程访问同一临界区进程里调用spin_lock_irqsave()是安全的在中断中不调用spin_lock()也没有问题。因为spin_lock_irqsave()可以保证这个CPU的中断服务程序不可能执行。但是如果CPU是多核的那么spin_lock_irqsave()不能屏蔽另外一个核的中断则另外那个核就可能造成并发问题。因此不管怎样在中断服务程序中也应该调用spin_lock()。 参考资料
《Linux设备驱动开发详解 —— 基于最新的Linux 4.0内核》 宋宝华 编著机械工业出版社