【发布时间】:2021-05-14 17:22:30
【问题描述】:
我正在尝试将缓存用作临时内存。在使用缓存之后,我不想存储任何修改过的缓存行。我开始知道我可以通过运行invd 指令来实现这一点。因为与wbinvd 不同,invd 使处理器的内部缓存无效(刷新)而不将它们存储到主内存中。
我写了一个内核模块来检查我是否可以执行invd指令。
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/init.h> /* Needed for the macros */
int new_invd(void){
asm volatile ("invd" : : : "memory");
return 1;
}
static int __init hello_start(void)
{
printk(KERN_INFO "Loading hello module...\n");
//check if invd instruction executes
printk(KERN_INFO "running invd\n", new_invd());
return 0;
}
static void __exit hello_end(void)
{
printk(KERN_INFO "Goodbye\n");
}
module_init(hello_start);
module_exit(hello_end);
编译并插入模块后,我得到Segmentation fault (core dumped) 和dmesg 显示,
[ 7525.227059] 正在加载你好模块... [ 7525.227088] 一般保护故障:0000 [#1] SMP
我使用asm volatile ("invd" : : : "memory"); 中提到的chromium。现在我认为我收到了错误,因为执行invd 违反了主内存和缓存的一致性,正如@Gunther Piez 在How can I do a CPU cache flush in x86 Windows? 中指出的那样。但是,我不确定是否是这种情况。
那么,为什么我得到这个segfault 有什么帮助吗?如果这是由于违反缓存核心,我该如何解决?如果没有,我该如何执行invd?
我正在使用Linux xxx 4.4.0-200-generic #232-Ubuntu SMP Wed Jan 13 10:18:39 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
cat /proc/cpuinfo 显示,
vendor_id : GenuineIntel
cpu family : 6
model : 158
model name : Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
【问题讨论】:
-
Linux 启动后你不能安全地执行
invd,尤其是在其他内核可能正在做任何事情的 SMP 系统中(即有一些脏缓存行)。丢弃所有最近的商店显然会破坏所有东西。 -
@PeterCordes 如果其他核心处于无填充模式,仍然是真的吗?
-
@PeterCordes,有没有
invd的替代品来实现同样的目标? -
不支持丢弃特定缓冲区的内容,而且我认为
invd仍然很慢。加上睡眠所有其他内核的成本(在深度睡眠刷新私有缓存的 CPU 模型上)并以某种方式确保甚至 L3 缓存同步,比如在运行这个临时缓冲区之前可能wbinvd(也非常慢)+@987654342 @(禁用中断,其他内核一直处于休眠状态)。几乎可以肯定的是,让硬件最终写回你的缓冲区对性能来说要好得多。保持小并重复使用它,也许它不会在使用之间写回。 -
查找支持 CAT 技术的 CPU。 Linux内核中甚至有(曾经?)驱动程序。 software.intel.com/content/www/us/en/develop/articles/…
标签: linux caching x86-64 kernel-module cpu-cache