c-在用户空间中启用写组合IO访问



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

如果我使用ioremap_wc重新映射内核中BAR的物理地址,然后将64个字节写入内核内部的BAR,我可以看到这64个字节是作为PCIe上的单个TLP写入的。如果我允许我的用户空间程序mmap具有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 0xd400000-0xd7fffffff],磁道写入组合,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。

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

相关内容

  • 没有找到相关文章

最新更新