在用户空间启用写入组合IO访问

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

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

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

希望将某些页面导出到用户空间的驱动程序通过使用mmap界面和其组合来完成

1) pgprot_noncached()

2) io_remap_pfn_range()remap_pfn_range()vm_insert_pfn()

通过PAT支持,正在添加一个新的API pgprot_writecombine 。 因此,驱动程序可以继续使用上述顺序,在步骤1中使用pgprot_noncached()pgprot_writecombine() ,然后使用步骤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],轨道写入组合,req写入组合,ret写入组合

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

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

我还检查了没有与PATconfiguration冲突的MTRR条目。 据我所见,所有的设置都是正确的,以便在用户空间中进行写入组合,但是使用PCIe分析器观察PCIe总线上的事务,那里的用户空间访问模式与从内核执行的相同写入完全不同在ioremap_wc调用之后。

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

我能做些什么来进一步debugging?

我目前正在运行在一个单一的sockets6芯i7-3930K。

我不知道这是否会有所帮助,但是这正是我如何在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]); }