12

我有一个带有用户空间驱动程序的 PCIe 设备。我正在通过 BAR 向设备写入命令,这些命令对延迟敏感,数据量很小(~64 字节),所以我不想使用 DMA。

如果我使用重新映射内核中 BAR 的物理地址,ioremap_wc然后将 64 字节写入内核内部的 BAR ,我可以看到 64 字节作为单个 TLP 在 PCIe 上写入。如果我允许我的用户空间程序进入mmap带有MAP_SHARED标志的区域,然后写入 64 字节,我会在 PCIe 总线上看到多个 TPL,而不是单个事务。

根据内核PAT 文档,我应该能够将写入组合的页面导出到用户空间:

想要将某些页面导出到用户空间的驱动程序通过使用 mmap 接口和结合

1)pgprot_noncached()

2 )io_remap_pfn_range()remap_pfn_range()vm_insert_pfn()

借助 PAT 支持,pgprot_writecombine正在添加一个新的 API。因此,驾驶员可以继续使用上述顺序, pgprot_noncached()或者pgprot_writecombine()在第 1 步中,然后在第 2 步中。

根据此文档,我的 mmap 处理程序中的相关内核代码如下所示:

 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);

 return io_remap_pfn_range(vma,
                           vma->vm_start,
                           info->mem[vma->vm_pgoff].addr >> PAGE_SHIFT,
                           vma->vm_end - vma->vm_start,
                           vma->vm_page_prot);

我的 PCIe 设备显示在 lspci 中,并且 BAR 按预期标记为可预取:

    Latency: 0, Cache Line Size: 64 bytes
    Interrupt: pin A routed to IRQ 11
    Region 0: Memory at d8000000 (64-bit, prefetchable) [size=32M]
    Region 2: Memory at d4000000 (64-bit, prefetchable) [size=64M]

当我mmap从用户空间调用时,我看到一条日志消息(设置了 debugpat 内核引导参数):

添加reserve_memtype [mem 0xd4000000-0xd7ffffff], track write-combining, req write-combining, ret write-combining

我还可以看到/sys/kernel/debug/x86/pat_memtype_listPAT 条目看起来正确并且没有重叠区域:

write-combining @ 0xd4000000-0xd8000000
uncached-minus  @ 0xd8000000-0xda000000

我还检查了没有与 PAT 配置冲突的 MTRR 条目。据我所见,一切都已正确设置为在用户空间中发生写入组合,但是使用 PCIe 分析器观察 PCIe 总线上的事务,用户空间访问模式与从内核执行的相同写入完全不同通话后ioremap_wc

为什么写入组合在用户空间中不能按预期工作?

我该怎么做才能进一步调试?

我目前在单插槽 6 核 i7-3930K 上运行。

4

1 回答 1

1

我不知道这是否会有所帮助,但这就是我在 PCIe 上进行写组合工作的方式。当然,它在内核空间中,但这符合英特尔文档。如果您遇到困难,值得一试。

全局定义:

unsigned int __attribute__ ((aligned(0x20))) srcArr[ARR_SIZE];

在您的功能中:

int *pDestAddr

for (i = 0; i < ARR_SIZE; i++) {
    _mm_stream_si32(pDestAddr + i, pSrcAddr[i]);
}
于 2014-04-23T22:52:25.723 回答