LWN:开发者争论split-lock检测机制!

关注了就能看到更多这么棒的文章哦~

Developers split over split-lock detection

By Jonathan Corbet
December 6, 2019

原文来自:https://lwn.net/Articles/806466/

"split lock"是指处理器在跨cache line边界的内存区域访问时会持有的一个底层memory-bus lock。大多数处理器都不支持split lock,不过x86支持。split lock机制对开发者来说会很方便,不过这个方便性是有伴随的代价的:一个split-lock指令就会占用memory bus大概1000个时钟周期长的时间。因此不少人都希望能去掉split-lock操作。不过少有人知的是,其实有一个能检测split lock的patch已经从2018年5月提出一直到现在都没合入,看来还没达到mainline的要求。

split lock本质上来说是一种非对齐的内存访问,x86架构上面通常总是倾向于允许这种访问。不过,普通的非对齐访问只会拖慢这个进程本身,而split lock则会拖慢整个系统。这1000个时钟周期的延迟,对实时系统来说格外无法忍受,而且其实split lock在任何系统上都可以用来作为DoS(拒绝服务)攻击手段。开发者基本上达成共识,大多数系统上都不应该允许使用split lock。

最近的Intel处理器支持配置成在split lock的时候陷入异常处理,这样就能让操作系统来决定是否允许这类操作。Fenghua Yu在2018年5月就提交了一个patch set来支持这种异常粗粒。LWN在一年之后就有介绍。尽管这个patch本身已经演进了不少,它的核心一直没有变:在打开这个功能的时候,user-space进程只要调用split lock,就会收到SIGBUS signal。其他情况下如果发生split lock该怎么处理,这一点一直在变。在今年十一月第10版的patch里面,kernel或者system firmware里的split lock则会导致kernel panic。

之所以采用这么严重的反应,主要是希望能让问题尽快得到处理。Yu举了几个例子,都是通过这个patch检测到的split lock,从而在kernel代码里进行了相应的fix。不过,只有在打开这个功能的系统上,代码创建split lock的时候,才能检测到。其实有相当多的运行场景是不符合这个条件的因为“split lock检测功能缺省是关闭的,毕竟这个检测会导致kernel panic或者用户进程被kill。只有在实时性要求高的系统上,或者出于debug目的在kernel参数窜地了split_lock_detect参数的情况下才会打开”。

这个功能是缺省关闭的,确保不会被广泛使用,这一点引起不少抱怨。Ingo Molnar认为这个功能必须缺省打开才有价值。Peter Zijlstra说:“这个功能必须缺省打开,否则总有一天会有问题没法用起来,最终连哪怕想用这个功能的人都用不起来。”

Zijlstra尤其担心firmware里面创建的split lock,他认为“经历了又长又痛苦的经历,我们才意识到如果BIOS可能会出错的话,那就一定会出错”。缺省打开split lock检测机制能有助于修复这些firmware里的split lock。否则的话,就会永远藏在firmware代码里,在用户想打开split-lock检测查自己问题的时候蹦出来干扰大家。

缺省打开,能强迫大家都去fix问题,看起来确实很有吸引力。不过缺省关闭也是有理由的:kill这些含有split lock的进程,是一个ABI改动,会对用户造成麻烦。就像Tony Luck说的:“缺省打开会很快引出应用程序被kill和kernel panic等抱怨,接下来就会捅到Linus那里去,然后根据不能导致兼容性问题的原则被revert掉。”

Zijlstra不这么认为,他觉得kernel问题大多数已经fix了,而user space代码里这种问题会很少,因为其他架构从来就没有支持split lock功能。对那些比较担心这一点的人,他提出了一个后续patch,允许split-lock检测功能在启动的时候进行控制,也增加了一个“warn-only"模式确保不会kill任何进程。

在这个新patch里面,他指出“这个patch要求kernel和firmware是没有split lock问题的”,他认为修复kernel的问题应该非常容易。不过,后来讨论中显示,可能并不是那么容易哦。具体来说,David Laight指出一个问题:kernel里atomic bitmask函数就很容易导致split lock操作。这里问题的核心是bitmask的类型被定已成unsigned long,不过开发者常用的则是一个int类型。这种情况下,就很容易出现非对齐的访问,有时候就会跨越cache-line边界从而导致split lock。

大家对于如何彻底解决这个问题,有很多不同看法。Yu提了一个复杂方案支持各种情况,希望能让atomic bit操作在所有用法下都是安全的,不过不少人觉得太太太复杂了。Zijlstra认为这个方案没法接受。Andy Lutomirski提出了另一个方案,就是修改atomic bit操作,改为32-bit值。这样带来的副作用就是只能支持最多32个bit定义了。Zijlstra指出,不少架构(alpha, ia64)其实已经是这么实现atomic bit操作的了,所以32位对kernel来说其实可能足够了。

Sean Christopherson对合入split lock检测功能还有一个担心:用来控制split-lock检测功能的bit是会以CPU core为单位来控制,而不是以CPU为单位。因此针对hyperthread情况来说,同一个core内的兄弟CPU也会收到影响。这个问题是在9月份刚刚意识到的,当时split-lock patch set已经经过了9个版本,关注度不高,不过既然现在已经发现了,那么肯定要在kernel处理好。

split-lock检测如果对整个系统都打开,那就没有问题。如果有人想要在某些时间段内打开或者关闭这一功能,就可能会出问题。尤其是在虚拟化场景更加麻烦,guest系统对是否打开split-lock检测这一方面的意见可能互不相同,或者跟host系统不同。解决方法,可能就是不允许guest系统来控制split-lock检测功能(当前是这么做的),或者只有在hyperthreading关闭的情况下才允许guest系统使用不同控制。目前还没有人提出建议利用core scheduling来确保运行在同一个core的所有进程都有一致的split-lock检测配置,不过后面肯定会有人提的。

所有这一切,都让这个很有价值的功能一直没能在黄金时间用起来。还不清楚是会尽快合入然后慢慢改,还是会继续改进完再合入。都有可能吧,毕竟最早也是要到5.6才能合入了。split lock检测致力于解决一些不必要的延迟,不过它自己却不得不一再延迟。。。

全文完

LWN文章遵循CC BY-SA 4.0许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注LWN深度文章以及开源社区的各种新近言论~

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值