26. 总线锁检测与处理

版权所有:

© 2021 Intel Corporation

作者:

26.1. 问题

分割锁是其操作数跨越两个缓存行的任何原子操作。由于操作数跨越两个缓存行,并且操作必须是原子的,因此系统会在CPU访问两个缓存行时锁定总线。

总线锁通过对回写(WB)内存的分割锁定访问或对非WB内存的任何锁定访问来获得。这通常比缓存行内的原子操作慢数千个周期。它还会扰乱其他核心的性能,并使整个系统瘫痪。

26.2. 检测

英特尔处理器可能支持以下一种或两种硬件机制来检测分割锁和总线锁。一些AMD处理器也支持总线锁检测。

26.2.1. 用于分割锁检测的#AC异常

从Tremont Atom CPU开始,当尝试分割锁操作时,分割锁操作可能会引发对齐检查(#AC)异常。

26.2.2. 用于总线锁检测的#DB异常

某些CPU能够在用户指令获取总线锁并执行后,通过#DB陷阱通知内核。这允许内核终止应用程序或强制执行节流。

26.3. 软件处理

内核#AC和#DB处理程序基于内核参数“split_lock_detect”处理总线锁。以下是不同选项的摘要

split_lock_detect=

#AC 用于分割锁

#DB 用于总线锁

off

不执行任何操作

不执行任何操作

warn (默认)

内核OOPs 警告每个任务一次,添加延迟,添加同步以防止多个核心并行执行分割锁。sysctl split_lock_mitigate 可用于避免延迟和同步。如果同时支持这两个特性,则在#AC中发出警告

警告每个任务一次并继续运行。

fatal

内核OOPs 向用户发送SIGBUS。如果同时支持这两个特性,则在#AC中致命错误

向用户发送SIGBUS。

ratelimit:N (0 < N <= 1000)

不执行任何操作

将总线锁速率限制为每个系统范围内每秒N个总线锁,并警告总线锁。

26.4. 用法

检测和处理总线锁可能会在各个领域找到用法

对于构建整合实时系统的实时系统设计人员来说,这至关重要。这些系统在某些核心上运行硬实时代码,并在其他核心上运行“不受信任”的用户进程。硬实时不能承受来自不受信任的进程的任何总线锁,从而损害实时性能。迄今为止,设计人员一直无法部署这些解决方案,因为他们无法阻止“不受信任”的用户代码生成分割锁和总线锁,从而阻止硬实时代码在总线锁定时访问内存。

它对于通用计算也很有用,可以防止访客或用户应用程序通过执行带有总线锁的指令来降低整个系统的速度。

26.5. 指导

26.5.1. off

禁用分割锁和总线锁的检查。如果存在以低速率触发这些事件的旧应用程序,从而不需要缓解,则此选项可能很有用。

26.5.2. warn

当检测到总线锁时,会发出警告,从而可以识别违规应用程序。这是默认行为。

26.5.3. fatal

在这种情况下,总线锁是不被允许的,并且该进程将被杀死。

26.5.4. ratelimit

指定系统范围内的总线锁速率限制N,其中 0 < N <= 1000。 这允许每秒高达N个总线锁的速率。 当总线锁速率超过限制时,通过总线锁#DB异常捕获的任何任务都会通过强制睡眠进行节流,直到速率再次低于限制。

在可以容忍最小影响,但必须防止最终的拒绝服务攻击的情况下,这是一种有效的缓解措施。 它允许识别违规进程并分析它们是恶意的还是只是编写不良。

选择 1000 的速率限制允许总线每秒锁定最多约七百万个周期(假设每个总线锁有 7000 个周期)。 在 2 GHz 处理器上,这将大约是 0.35% 的系统减速。