【问题标题】:Linux PCI Driver, mmap prefetchingLinux PCI 驱动程序,mmap 预取
【发布时间】:2012-10-06 08:08:10
【问题描述】:

我有一个 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)

【问题讨论】:

  • 您的 PCI 设备是否将自己宣传为可预取的? (内存条中的第 3 位。)
  • 不,PCI 标志是 0x0040200,(根据我的标头,PREFETCHABLE 标志是 0x2000)

标签: linux driver mmap pci


【解决方案1】:

我找到了解决办法!

正如一位同事所建议的,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;

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-17
    • 2020-08-31
    • 2014-05-18
    • 1970-01-01
    • 1970-01-01
    • 2016-04-26
    • 2013-10-02
    • 1970-01-01
    相关资源
    最近更新 更多