我有一个带有用户空间驱动程序的PCIe设备。我正在通过BAR向设备写命令,命令对延迟敏感,数据量很小(~64字节),所以我不想使用DMA。
如果我使用ioremap_wc
重新映射内核中BAR的物理地址,然后将64字节写入内核中的BAR ,我可以看到64字节是写在PCIe上作为单个TLP。如果我允许我的用户空间程序mmap
具有MAP_SHARED
标志的区域然后写入64字节,我会在PCIe总线上看到多个TPL,而不是单个事务。
根据内核PAT documentation,我应该可以将写入组合页面导出到用户空间:
想要将某些页面导出到用户空间的驱动程序通过使用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
我还检查过没有与PAT配置冲突的MTRR条目。据我所知,所有内容都设置正确,以便在用户空间中进行写入组合,但是使用PCIe分析器观察PCIe总线上的事务,那里的用户空间访问模式与从内核执行的相同写入完全不同ioremap_wc
来电后。
为什么写入组合在用户空间中没有按预期工作?
我可以做些什么来进一步调试?
我目前正在使用单插槽6核i7-3930K。
答案 0 :(得分: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]);
}