Linux PCI 驱动程序、mmap 预取

标签 linux driver mmap pci

我有一个 PCI 设备、它的 Linux 驱动程序和一个用户空间应用程序。应用程序mmap是通过驱动程序获取PCI设备的第一个BAR。所有访问都是通过 32 位整数完成的,这一点很重要,因为读/写寄存器可能会产生副作用(启动操作等)。

在 x86 平台上,这非常有效。但是,我刚刚迁移到 ARM 平台,并且有一个奇怪的行为:

  • 从驱动程序读取/写入行为正确
  • 从用户空间读取会触发 64 字节 PCI 读取请求,我的设备无法满足该请求,因为它只接受 32 位访问(+由于副作用,我不希望这样做)。

我认为问题在于 mmap 想要预取一些数据并发出此 64 字节读取。 我是否缺少一个标志或可能禁用某种 mmap 预取的东西?

我当前在驱动程序端的 mmap 实现很简单

vma->vm_flags |= VM_RESERVED;
remap_pfn_range(vma,vma->vm_start,  pfn, Size_UL, vma->vm_page_prot)

最佳答案

我找到了解决方案!

正如一位同事所建议的,64字节是一个缓存行,这可能是一个缓存机制忽略了我的“不可预取”信息,因为它在mmap()期间丢失了(尽管在x86上保留了......) ,所以我必须将这些标志添加到 vma 以防止缓存:

vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot) | L_PTE_PRESENT |
                         L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY;

实际上不确定是否需要所有标志,但是,嘿,它有效!

关于Linux PCI 驱动程序、mmap 预取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12911075/

相关文章:

C++ 文件内存映射容器类似于 std::vector/boost::array

C++ MMap 一个文件到内存,然后获取一个文件描述符到该内存

c++ - 内存映射文件和指向易失对象的指针

php - 无法加载资源: the server responded with a status of 449 (Woocommerce)

c++ - 调试 Visual Studio 开发与 "Linux"开发的工作流方面?

c - wait4 不阻塞父线程

Linux 设备文件丢失

linux - 在 Linux 中重命名多个文件并删除多余字符

windows - 如何从内部卸载 Windows 内核模式驱动程序?

sql-server - ClassNotFoundException - com.microsoft.jdbc.sqlserver.SQLServerDriver