我读了这篇文章为什么内存区域会被标记为非缓存? 但是除了“与硬件通信”(例如 DMA)的内存区域之外,没有提到其他原因。
还有其他充分的理由将内存标记为不可缓存吗?
mmap()
和 MAP_NOCACHE
标志将内存从用户空间标记为不可缓存,不是吗?
还有其他充分的理由将内存标记为不可缓存吗?
不是真的,至少在 Linux 上不是。然而,存在许多可能的缺点。事实上,您不能在 Linux 中使用
mmap
创建未缓存的映射。
你提到的
MAP_NOCACHE
标志在 Linux 中不存在,它在 macOS 中存在,即使在那里它也不意味着未缓存的内存,它似乎与内核页面缓存有关(参见 man 2 mmap
for macOS ).
一个可以被认为对未缓存内存映射感兴趣的应用程序是保护来自架构缓存侧通道的数据,例如Meltdown。为用户空间提供创建未缓存映射的能力的可能性实际上在不久前被考虑用于实现
memfd_secret
系统调用,但在 Andy Lutomirski 的建议下被废弃,他解释说:
我还没有准备好在 x86 上确认未缓存的映射。我很好 允许特权用户在 x86 上创建 UC 内存的概念 用于测试和实验,但它是一大堆蠕虫 一般的。立即想到的问题是:
性能和 DoS 潜力。 UC 将具有奇怪的、依赖于体系结构和平台的性能特征。据我所知, 甚至访问语义也可能依赖于体系结构。我不是 确信可以使用未缓存的在 C 中编写可移植代码 特征。我还担心某些操作(未对齐的锁, 例如,可能还有任何锁定的访问)将触发总线锁定 x86,这取决于 CPU 和内核配置,要么 DoS all 其他 CPU 或发送信号。 (或导致管理程序终止或 否则惩罚 VM,这将是令人讨厌的。)
正确性。我有报告称不同的 x86 管理程序对 UC 映射做不同的事情,包括将它们视为常规 世界银行映射。所以当你要求的时候你得到的内存类型 “未缓存”实际上可能不是未缓存的。
UC 确实是一个 MMIO 功能,而不是“保护我的数据”功能。滥用 保护数据当然很有趣,但我离 确信这是明智的。我特别不相信 猴子修补程序以在需要时使用未缓存的内存 常规的 malloced 内存是一件合理的事情。