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内核》 宋宝华 编著,机械工业出版社

相关推荐
C雨后彩虹5 小时前
任务最优调度
java·数据结构·算法·华为·面试
Chan169 小时前
【 Java八股文面试 | JavaSE篇 】
java·jvm·spring boot·面试·java-ee·八股
辞砚技术录9 小时前
MySQL面试题——索引2nd
数据库·mysql·面试
码农水水11 小时前
中国邮政Java面试:热点Key的探测和本地缓存方案
java·开发语言·windows·缓存·面试·职场和发展·kafka
a程序小傲11 小时前
小红书Java面试被问:TCC事务的悬挂、空回滚问题解决方案
java·开发语言·人工智能·后端·python·面试·职场和发展
a努力。11 小时前
国家电网Java面试被问:最小生成树的Kruskal和Prim算法
java·后端·算法·postgresql·面试·linq
NAGNIP12 小时前
一文搞懂机器学习中的学习理论!
算法·面试
CCPC不拿奖不改名13 小时前
数据处理与分析:数据可视化的面试习题
开发语言·python·信息可视化·面试·职场和发展
柒.梧.14 小时前
SSM常见核心面试问题深度解析
java·spring·面试·职场和发展·mybatis
ssshooter16 小时前
复古话题:Vue2 的空格间距切换到 Vite 后消失了
前端·vue.js·面试