【发布时间】:2012-06-28 22:52:22
【问题描述】:
我正在尝试为 PCIe BAR 编写具有自定义 mmap() 函数的驱动程序,目的是使此 BAR 可缓存在处理器缓存中。我知道这不是实现最高带宽的最佳方式,而且写入的顺序是不可预测的(在这种情况下也不是问题)。
这类似于How would one prevent MMAP from caching values?中描述的内容
处理器是 Sandy Bridge i7,PCIe 设备是 Altera Stratix IV dev。板。
首先,我尝试在 CentOS 5 (2.6.18) 上执行此操作。我更改了 MTRR 设置以确保 BAR 不在不可缓存的 MTRR 内,并使用 io_remap_pfn_range() 并清除了 _PAGE_PCD 和 _PAGE_PWT 位。读取按预期工作:读取返回正确的值并且第二次读取到同一地址并不一定会导致读取转到 PCIe(在 FPGA 中检查了读取计数器)。但是,写入导致系统冻结,然后重新启动,而日志或屏幕上没有任何消息。
其次,我尝试在支持 PAT 的 CentOS 6 (2.6.32) 上执行此操作。结果是一样的:读取工作正常,写入导致系统冻结并重新启动。有趣的是,非临时/写入组合的完整高速缓存行写入 (AVX/SSE) 按预期工作,即它们总是转到 FPGA 并且 FPGA 观察到完整的高速缓存行写入,然后读取返回正确的值。但是,简单的 64 位写入仍然会导致系统冻结/重启。
我还尝试在驱动程序代码中 ioremap_cache() 然后 iowrite32()。结果是一样的。
我认为这是一个硬件问题,但如果有人能分享任何关于正在发生的事情的想法,我将不胜感激。
编辑:我能够在 CentOS 6 上捕获 MCE 消息:机器检查异常:5 Bank 5:be2000000003110a。
我还在 2-socket Sandy Bridge (Romley) 上尝试了相同的代码:读取和非临时写入行为是相同的,简单写入不会导致 MCE/崩溃但对系统状态没有影响,即内存中的值不变。
另外,我在旧的 2-socket Nehalem 系统上尝试了相同的代码:简单的写入也会导致 MCE,尽管代码不同。
【问题讨论】: