大内核锁将何去何从

大内核锁作为Linux内核早期的互斥机制,虽然逐渐被自旋锁取代,但由于其特殊性,至今仍存在。文章探讨了大内核锁的历史背景、存在的问题,以及Linux开发者们如何尝试优化和最终淘汰它的努力。
摘要由CSDN通过智能技术生成

大内核锁这个简单且不常用的内核加锁机制一直是内核开发者之间颇具争议的话题。它在早期linux版本里的广泛使用,从2.4内核开始逐渐被各种各样的自旋锁替代,可是直到现在还不能完全将它抛弃;它曾经使用自旋锁实现,到了2.6.11版修改为信号量,可是在2.6.26-rc2又退回到使用自旋锁的老路上;它甚至引发了linux的创始人Linus Torvalds和著名的完全公平调度(CFS)算法的贡献者Ingo Molnar之间的一场争议。这究竟是怎么回事呢?

1.1         应运而生,特立独行

使用过自旋锁或信号量这些内核互斥机制的人几乎不会想到还有大内核锁这个东西。和自旋锁或信号量一样,大内核锁也是用来保护临界区资源,避免出现多个处理器上的进程同时访问同一区域的。但这把锁独特的地方是,它不象自旋锁或信号量一样可以创建许多实例或者叫对象,每个对象保护特定的临界区。事实上整个内核只有一把这样的锁,一旦一个进程获得大内核锁,进入了被它保护的临界区,不但该临界区被锁住,所有被它保护的其它临界区都将无法访问,直到该进程释放大内核锁。这看似不可思议:一个进程在一个处理器上操作一个全局的链表,怎么可能导致其它进程无法访问另一个全局数组呢?使用两个自旋锁,一个保护链表,另一个保护数组不就解决了吗?可是如果你使用大内核锁,效果就是这样的。

大内核锁的产生是有其历史原因的。早期linux版本对对称多处理(SMP)器的支持非常有限,为了保证可靠性,对处理器之间的互斥采取了‘宁可错杀三千,不可放过一个’的方式:在内核入口处安装一把‘巨大’的锁,一旦一个处理器进入内核态就立刻上锁,其它将要进入内核态的进程只能在门口等待,以此保证每次只有一个进程处于内核态运行。这把锁就是大内核锁。有了大内核锁保护的系统当然可以安全地运行在多处理器上:由于同时只有一个处理器在运行内核代码,内核的执行本质上和单处理器没有什么区别;而多个处理器同时运行于进程的用户态也是安全的,因为每个进程有自己独立的地址空间。但是这样粗鲁地加锁其缺点也是显而易见的:多处理器对性能的提示只能体现在用户态的并行处理上,而在内核态下还是单线执行,完全无法发挥多处理器的威力。于是内核开发者就开始想办法逐步缩小这把锁保护的范围。实际上内核大部分代码是多处理器安全的,只有少数全局资源需要需要在做互斥加以保护,所以没必要限制同时运行于内核态处理器的个数。所有处理器都可随时进入内核态运行,只要把这些需要保护的资源一一挑出来,限制同时访问这些资源的处理器个数就可以了。这样一来,大内核锁从保护整个内核态缩小为零散地保护内核态某些关键片段。这是一个进步,可步伐还不够大,仍有上面提到的,‘锁了卧室厨房也没法进’的毛病。随着自旋锁的广泛应用,新的内核代码里已经不再有人使用大内核锁了。

1.2      食之无味,挥之不去

既然已经有了替代物,大内核锁应该可以‘光荣下岗’了。可事实上没这么简单。如果大内核锁仅仅是‘只有一个实例’的自旋锁,睿智的内核开发者早就把它替换掉了:为每一种处于自旋锁保护下的资源创建一把自旋锁,把大内核锁加锁/解锁替换成相应的自旋锁的加锁/解锁就可以了。但如今的大内核锁就象一个被宠坏的孩子,内核在一些关键点给予了它许多额外关照,使得大内核锁的替换变得有点烦。下面是Ingo Molnar在一封名为 ’kill the Big Kernel Lock (BKL)’的邮件里的抱怨:

The biggest technical complication is that the BKL is unlike any other lock: it "self-releases" when schedule() is called. This makes the BKL spinlock very "sticky", "invisible" and viral: it's very easy to add it to a piece of code (even unknowingly) and you never really know whether it's held or not. PREEMPT_BKL made it even more invisible, because it made its effects even less visible to ordinary users.

这段话的大意是:最大的技术难点是大内核锁的与众不同:它在调用schedule()时能够‘自动释放’。这一点使得大内核锁非常麻烦和隐蔽:它使你能够非常容易地添加一段代码而几乎从不知道它锁上与否。PREEMPT_BKL选项使得它更加隐蔽,因为这导致它的效果在普通用户面前更加‘遁形’。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值