Linux 如何防止 MMAP 缓存值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9890728/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How would one prevent MMAP from caching values?
提问by Sean Madden
I've written a linux driver that ioremaps exports PCI BAR0 for a particular device to a sysfs binary attribute allowing userspace to directly control it.
我编写了一个 linux 驱动程序,ioremaps 将特定设备的 PCI BAR0 导出到 sysfs 二进制属性,允许用户空间直接控制它。
The problem rears when I attempt to MMAP on top of the attribute to directly access that bit of memory (from a userland program). Reads succeed just fine and return expected values, though when I write to that memory it appears to be cached somewhere between the kernel and memory and not delivered to the GMCH root complex (and therefore the device). What I'd like to do is have an implicit write memory barrier after each access.
当我尝试在属性之上 MMAP 以直接访问该位内存(从用户态程序)时,问题就出现了。读取成功并返回预期值,但当我写入该内存时,它似乎缓存在内核和内存之间的某个位置,而不是传递到 GMCH 根联合体(因此也不会传递到设备)。我想做的是在每次访问后都有一个隐式写内存屏障。
- Is there any way to prevent the kernel from caching writes to a mmap-ed bit of memory?
- 有什么办法可以防止内核将写入缓存到 mmap-ed 内存位?
Follow ups:
跟进:
- Is calling msync()after every access the "accepted" way to do this?
- 每次访问后调用msync()是否是“接受”的方式来做到这一点?
采纳答案by Sean Madden
Going to go ahead and answer this one myself with my solution.
继续用我的解决方案自己回答这个问题。
In the Kernel driver from my sysfs mmap function, there is a macro in /include/asm/pgtable.h that sets the proper flags for a nocache'd pfn remap. It looks like this:
在我的 sysfs mmap 函数的内核驱动程序中,/include/asm/pgtable.h 中有一个宏,它为 nocache 的 pfn 重映射设置了正确的标志。它看起来像这样:
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
if (io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
vma->vm_end - vma->vm_start,
vma->vm_page_prot))
return -EAGAIN;
Additionally, in the userland mmap, I used the MAP_SHARED flag in the mmap flags argument.
此外,在用户态 mmap 中,我在 mmap flags 参数中使用了 MAP_SHARED 标志。
The combination of the two ultimately did the trick.
两者的结合最终成功了。
回答by blueshift
Might ioremap_nocache()
help?
可能有ioremap_nocache()
帮助吗?