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