在 ARMv8-A Linux 上禁用 CPU 缓存 (L1/L2)

sil*_*van 4 linux caching arm

我想在运行 Linux 的 ARMv8-A 平台上禁用低级缓存,以测量优化代码的性能,独立于缓存访问。

对于 Intel 系统,我找到了以下资源(Is there a way to disable CPU cache (L1/L2) on a Linux system?),但由于指令集不同,无法直接应用。

到目前为止,我有一个内核模块,它改变相应的系统寄存器以禁用指令和数据缓存。

#include <linux/module.h>

int init_module(void)
{
  int64_t value;

  asm volatile("\
    MRS %0, SCTLR_EL1     // Read SCTLR_EL1 into Xt\n\
    BIC %0, %0, (1<<2)    // clear bit 2, SCTLR_EL1.C\n\
    BIC %0, %0, (1<<12)   // clear bit 12, SCTLR_EL1.I\n\
    MSR SCTLR_EL1, %0     // Write Xt to SCTLR_EL1\n\
  " : "+r" (value));

  return 0;
}

void cleanup_module(void)
{
  int64_t value;

  asm volatile("\
    MRS %0, SCTLR_EL1    // Read SCTLR_EL1 into Xt\n\
    ORR %0, %0, (1<<2)   // set bit 2, SCTLR_EL1.C\n\
    ORR %0, %0, (1<<12)  // set bit 12, SCTLR_EL1.I\n\
    MSR SCTLR_EL1, %0    // Write Xt to SCTLR_EL1\n\
  ": "+r" (value));
}

MODULE_LICENSE("GPL");
Run Code Online (Sandbox Code Playgroud)

但是,加载时会导致系统完全冻结(当我在系统寄存器中设置相应位时)。我的猜测是我仍然需要某种缓存清除,但我在 ARM 手册中没有找到任何有用的东西。

任何人都有一些有用的提示,我如何才能成功禁用 ARM 上的缓存或我在这里缺少什么?谢谢。

Not*_*hat 6

一般来说,这是行不通的,原因有几个。

首先,清除 SCTLR.C 位只会使所有数据访问不可缓存。并防止分配到任何缓存中。缓存中的任何数据仍然存在于缓存中,尤其是最近写入的任何内容的脏行;考虑当您的函数返回并且调用者尝试恢复它现在正在访问的内存中甚至不存在的堆栈帧时会发生什么。

其次,单处理器ARMv8系统很少;假设您正在运行 SMP Linux,并且突然禁用模块加载器恰好安排在哪个 CPU 上的缓存,那么即使忽略第一点,事情也会很快走下坡路。Linux 期望所有 CPU 彼此一致,如果违反该假设,通常会非常迅速地崩溃。请注意,为此甚至不值得冒险使用 SMP 交叉调用;可以说,即使尝试在禁用缓存的情况下运行 Linux的唯一安全方法是确保它们从一开始就从未启用,除非......

第三,无法保证 Linux 甚至可以在禁用缓存的情况下运行。在当前的硬件上,内核(更不用说用户空间)中的所有锁定和原子操作都依赖于独占访问指令。虽然 CPU 集群将为可缓存内存实现架构上所需的本地和全局独占监视器(通常作为缓存机制本身的一部分),但是否实现了用于不可缓存访问的全局独占监视器取决于系统,因为这样的东西必须在 CPU 外部(通常在互连或内存控制器中)。许多系统没有实现这样的全局监视器,在这种情况下,对外部存储器的独占访问可能会出错、不做任何事情或其他各种实现定义的行为,这将导致 Linux 崩溃或死锁。在这样的系统上在关闭缓存的情况下运行 Linux 实际上是不可能的——仅仅为了让 UP arm64 内核工作(SMP 实际上是不可能的)而进行的大量黑客攻击是不切实际的;祝用户空间好运。

然而,碰巧的是,最糟糕的问题不是这些,而是​​:

...为了衡量优化代码的性能,独立于缓存访问。

如果代码打算在禁用缓存的情况下在部署中运行,那么从逻辑上讲,它不能在 Linux 下运行,因此花在破解 Linux 上的努力最好花在更现实的执行环境中的基准测试上,以便结果是其实有代表性。在另一方面,如果它用于与高速缓存运行启用(在Linux或任何其他操作系统),然后禁用会给无意义的结果,成为浪费时间的缓存标杆。“优化”例如在实践中不存在的指令提取带宽瓶颈不会引导您走向正确的方向。