我想写一个PCIe BAR自定义mmap()
函数的驱动程序,其目的是使这个BAR可以在处理器缓存中缓存。我知道这不是实现最高带宽的最佳方式,并且写入顺序是不可预测的(在这种情况下也不是这样)。mmap如何缓存PCIe 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银行5:be2000000003110a。
我也在2插槽Sandy Bridge(Romley)上试过相同的代码:读取和非暂时写入行为是相同的,简单的写入不会导致MCE /崩溃但对系统状态没有影响,即值内存不会改变。
此外,我在旧的2插座Nehalem系统上尝试了相同的代码:简单写入也会导致MCE,但代码不同。