【问题标题】:Set memory as uncacheable through x86 PAT table通过 x86 PAT 表将内存设置为不可缓存
【发布时间】:2012-02-09 11:00:54
【问题描述】:

我想在用户空间进程中将内存范围设置为不可缓存(Linux、x86-86)。 This question 很接近,但只提到了与物理内存一起工作的 MTRR 寄存器。我想使用 PAT 表来做到这一点,因为它们提供了更细粒度的控制,它们允许逐页将虚拟内存设置为不可缓存。

Linux 文档Documentation/x86/pat.txt 建议应该有一些带有mmapSYNC 标志的东西,但我在实践中找不到如何做到这一点。理想情况下,我想使用诸如mprotect(address, range, O_UNCACHABLE) 之类的电话。

【问题讨论】:

  • madvise/mlock足够了吗?
  • 不,看起来这些只影响虚拟映射(无论页面是在 RAM 中还是在磁盘上),但它们似乎不影响缓存...
  • 为什么要使虚拟页面不可缓存?在正常情况下,您仅将未缓存的内存用于设备映射的 IO 或内存。这就是接口仅提供对物理内存的访问的原因。关闭缓存很可能是个坏主意。 x86 有特殊说明来暗示不太可能重用并且不需要缓存。这应该足以调整性能。如果您知道自己在做什么并且确实需要关闭缓存,您可以编写一个内核模块来自己提供用户级界面。但这真的是你想做的吗?
  • 这是一个研究项目(如果想法有用,最终目标是提出硬件修改)。如果初始验证可以在真实硬件上完成,那总是可取的,因为替代方案是使用比硬件慢一百万倍的架构模拟器......

标签: linux x86


【解决方案1】:

我建议编写一个内核模块来为用户级进程提供必要的接口。在内核模块内部可以使用set_memory_uc来控制页面属性。

关于模拟器:它应该慢十到千倍——而不是一百万倍——除非你在门级进行模拟。不要忘记考虑编写内核模块所花费的时间。如果您需要几周的时间来编写和调试模块,您最好使用模拟器进行一次性实验。

【讨论】:

    【解决方案2】:

    根据 ARM 平台上的各种开发人员问题,代码将是:

    fd = open("/dev/mem", O_RDWR|O_SYNC);
    uptr = mmap(addr, length, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_LOCKED, fd, off);
    

    参考:

    【讨论】:

    • 使用此代码,您可以访问物理地址范围,但您还必须保留它或以某种方式告诉内核不要使用它。如果你不做坏事就会发生......
    猜你喜欢
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 2012-08-13
    • 2011-10-31
    • 1970-01-01
    • 1970-01-01
    • 2012-08-14
    相关资源
    最近更新 更多