【翻译】split lock检测与处理

简介: > 本文在解读 https://lwn.net/Articles/790464/ 的基础上,加入自己理解,与原文存在差异。 ### 从地址不对齐访问到split lock Intel CPU微架构允许不对齐的内存访问,但ARM、RISC-V等架构却不允许。在众多的不对齐中,一个特殊的场景是:原子操作的操作数(由于地址不对齐)跨越两个cache lines,Intel将之叫做spl

本文在解读 https://lwn.net/Articles/790464/ 的基础上,加入自己理解,与原文存在差异。

从地址不对齐访问到split lock

Intel CPU微架构允许不对齐的内存访问,但ARM、RISC-V等架构却不允许。在众多的不对齐中,一个特殊的场景是:原子操作的操作数(由于地址不对齐)跨越两个cache lines,Intel将之叫做split lock。它有两个特征:

  1. 原子操作,即汇编指令包含Lock前缀;
  2. 操作数地址不对齐,还跨越两个cache lines;

其实大部分吃瓜群众都不知道这个特性,但是它却对应用性能影响极大。最近,Intel工程师Fenghua Yu同学正在开发一组内核补丁,用于检测和处理split lock,现在已经发出了第8版code review。阿里巴巴在多年前就意识到split lock的危害,在线上实施了大规模监控,并采取必要隔离措施。

下面通过一小段代码给吃瓜群众一个感性的认识:

  1 #include<stdio.h>
  2 #include <sys/mman.h>
  3 
  4 #pragma pack(push,2)
  5 struct counter
  6 {
  7     char buf[62];
  8     long long c;
  9 };
 10 #pragma pack(pop)
 11 
 12 int main () {
 13     struct counter *p;
 14     int size = sizeof(struct counter);
 15     int prot = PROT_READ | PROT_WRITE;
 16     int flags = MAP_PRIVATE | MAP_ANONYMOUS;
 17 
 18     p = (struct counter *) mmap(0, size, prot, flags, -1, 0);
 19 
 20     while(1) {
 21         __sync_fetch_and_add(&p->c, 1);
 22     }
 23 
 24     return 0;
 25 }

Intel cpu中,一个cache line 只有64个字节,struct counter中的成员 c 占8个字节,buf填充了62个字节。因此,一旦访问成员c,就涉及两个cache lines的内容的拼接;代码21行中,执行原子操作 __sync_fetch_and_add()会触发split lock。

split lock 的危害

Intel处理器很贴心,自动处理了不对齐的内存访问,甚至能保证split lock操作的正确性;但是也给程序的性能埋下一颗很难被发现的雷。

学过体系结构的同学都应该知道,缓存一制性协议MESI只能保证cache line粒度的一致性。同时访问两个cache lines不是常见操作,为保证split lock的原子性,设计硬件时使用特殊逻辑(冷路径)来处理:锁住整个访存总线,阻止其它逻辑cpu访存。

从原理出发,我们很容易想到,锁住总线将导致其它core上访存操作受阻,宏观表现为平均访存延时显著上升。为不让各位看官白走一趟,小编在自己的skylake机器上测了一组数据,随着split lock速率的增加,访存延迟呈指数恶化。

img

云场景下,在Guest中执行一个用户态进程,就可以阻塞物理机上其它核的访存操作,导致整机性能下降;极端情况下,甚导致整机的拒绝服务(DoS)攻击。这是一个严重的故障隔离问题。

解决方案

Intel 即将发布的下一代处理器 (Tremont和Ice Lake) 新增了Alignment Check (#AC)异常,并提供一个硬件开关。当开关使能的情况下,cpu产生split lock时,可以触发异常。至于采取什么动作就取决于注册的异常处理程序了,这正是Fenghua同学要做的事。而在早期的cpu上,只能通过perf监控sq_misc.split_lock 事件的数量,用于调试目的。

接下来,我们来看看这组内核补丁是如何处理#AC异常的。从整体看,可以将一个机器上运行的代码分为三类:固件、内核、用户态软件。

如果split lock出现在内核中,只打印warning,然后关闭当前cpu的检测功能。报出warning之后,重新执行被打断的指令,系统继续运行。是打印warning还是直接panic,是社区当前讨论的一个焦点。比较合理的解释是:内核中产生split lock是bug,但是该bug没有严重到需要直接panic。

如果split lock出现在用户态程序中,默认会发送一个SIGBUS信号,导致进程异常退出。只有当开发人员修复后才能正常运行程序。

当split lock出现在系统固件代码中,系统将会夯(hang)住。之所以这么设计,是内核开发人员担心,如果不暴露问题,固件厂商永远不会关注修复这类问题。

处理split lock的方式,有warning,sigbus, hang,都不是省油的灯。我们可能会担心,代码我改不了,一旦出现了split lock怎么办?好在设计者提供了关闭接口:

  1. 在内核启动参数中加入nosplit_lock_detect
  2. echo 0 > /sys/devices/system/cpu/split_lock_detect

这组内核补丁经过多轮review,社区的反馈都比较积极,包括Thomas Gleixner和Ingo Molnar等大佬。虽然还剩下一些小问题,预计不久将被合入内核主线。

号外

如何在现有的cpu上检测split lock呢?

perf stat -e cpu/event=0xf4,umask=0x10/ -a -I 1000  

其中 event=0xf4, umask=0x10 对应PMU事件sq_misc.split_lock。

相关文章
|
2月前
|
机器学习/深度学习 Web App开发 编解码
论文精度笔记(四):《Sparse R-CNN: End-to-End Object Detection with Learnable Proposals》
Sparse R-CNN是一种端到端的目标检测方法,它通过使用一组可学习的稀疏提议框来避免传统目标检测中的密集候选框设计和多对一标签分配问题,同时省去了NMS后处理步骤,提高了检测效率。
44 0
论文精度笔记(四):《Sparse R-CNN: End-to-End Object Detection with Learnable Proposals》
|
6月前
|
计算机视觉
【CV大模型SAM(Segment-Anything)】如何保存分割后的对象mask?并提取mask对应的图片区域?
【CV大模型SAM(Segment-Anything)】如何保存分割后的对象mask?并提取mask对应的图片区域?
【CV大模型SAM(Segment-Anything)】如何保存分割后的对象mask?并提取mask对应的图片区域?
|
3月前
|
存储 算法
RT-mutex 实现设计【ChatGPT】
RT-mutex 实现设计【ChatGPT】
|
4月前
|
自然语言处理
预训练模型STAR问题之Doc2Bot数据集中结构信息的问题如何解决
预训练模型STAR问题之Doc2Bot数据集中结构信息的问题如何解决
|
7月前
|
异构计算 Docker Python
ModelScope问题之加载模型时报错size mismatch如何解决
ModelScope镜像是指用于在ModelScope平台上创建和管理的容器镜像,这些镜像包含用于模型训练和推理的环境和依赖;本合集将说明如何使用ModelScope镜像以及管理镜像的技巧和注意事项。
142 0
|
数据处理
LIO-SAM代码逐行解读(3)-特征点提取
LIO-SAM代码逐行解读(3)-特征点提取
289 0
|
算法
word2vec深入浅出,保证你一看就会(1)
下一篇地址 http://www.atatech.org/articles/55128word2vec 是现在在自然语言处理中非常非常实用的技术,word2vec一般的用途通常有两种,第一种是其他复杂的神经网络模型的初始化,还有一种是把词与词之间的相似度来作为某个模型的特征。word2vec的最大优
7640 0