【翻译】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。

相关文章
|
运维 Linux Windows
【帕鲁更新攻略】如何快速在阿里云上更新游戏服务端版本
幻兽帕鲁游戏服务端版本升级后,需要玩家同步更新才能继续游戏,您可以按照以下操作完成游戏服务端升级。
49585 840
【帕鲁更新攻略】如何快速在阿里云上更新游戏服务端版本
|
缓存 运维 Shell
幻兽帕鲁爆内存优化方案
最近有很多小伙伴反馈说4C16G的服务器玩时间久了经常出现内存过满自动重启的情况,现在总结下linux和windows系统下怎么进行优化。
|
网络协议 前端开发 Unix
QEMU&KVM-2 Live Migration
虚拟机的迁移是指把一台VM上的OS迁移到另外一台VM,两个VM可以run在不同的物理机上。 包括:Offline Migration和Live Migration。这里讲讲比较常用的Live Migration(热迁移)。 在热迁移过程中,Guest OS完全无感,其运行的任务,在快速迁移过后能继续运行。 首先,对于Guest OS从一个VM迁移到其他VM,涉及到对register配置,di
8166 0
QEMU&KVM-2 Live Migration
|
运维 监控 Linux
iofsstat:帮你轻松定位 IO 突高,前因后果一目了然 | 龙蜥技术
磁盘被打满到底是真实的业务需求量上来了呢?还是有什么野进程在占用 IO? iofsstat 帮你精准定位。
iofsstat:帮你轻松定位 IO 突高,前因后果一目了然 | 龙蜥技术
|
弹性计算 Linux 数据安全/隐私保护
【阿里云幻兽帕鲁】搭建 密码 存档 使用 费用 常见问题合集
本文持续更新幻兽帕鲁玩家在阿里云上遇到的问题及解法。
66518 91
【阿里云幻兽帕鲁】搭建 密码 存档 使用 费用 常见问题合集
|
弹性计算 运维 Linux
地图在人物不在的存档修复
地图在人物不在的存档修复
|
弹性计算 Linux 网络安全
阿里云ECS健康诊断产品详解
介绍阿里云ECS健康诊断产品详情和使用案例,包括各个产品概念、控制、OpenAPI、SDK等。
|
云安全 弹性计算 安全
Linux服务器中了病毒后的清理方法
Linux服务器中了病毒后的清理方法
Linux服务器中了病毒后的清理方法
|
Linux 网络安全
CentOS 7 下升级 OpenSSH 7.4p1 到 OpenSSH 8.4p1
CentOS 7 下升级 OpenSSH 7.4p1 到 OpenSSH 8.4p1
832 0