Linux内核与驱动面试经典“小”问题集锦(3)

接前一篇文章: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内核》 宋宝华 编著,机械工业出版社

相关推荐
ShineSpark35 分钟前
C++面试2——C与C++的关系
c语言·c++·面试
永远有多远.1 小时前
【高频面试题】LRU缓存
java·缓存·面试
每次的天空4 小时前
Android第三次面试总结之网络篇补充
android·网络·面试
Hello World......6 小时前
互联网大厂Java面试:从Spring到微服务的全面探讨
java·spring boot·spring cloud·微服务·面试·技术栈·互联网大厂
supingemail17 小时前
面试之 Java 新特性 一览表
java·面试·职场和发展
laowangpython19 小时前
MySQL基础面试通关秘籍(附高频考点解析)
数据库·mysql·其他·面试
默心1 天前
运维工程师面试经验分享
运维·经验分享·面试
〆、风神1 天前
面试真题 - 高并发场景下Nginx如何优化
java·nginx·面试
独行soc2 天前
2025年渗透测试面试题总结-阿里云[实习]阿里云安全-安全工程师(题目+回答)
linux·经验分享·安全·阿里云·面试·职场和发展·云计算
真的没有脑袋2 天前
概率相关问题
算法·面试