在/proc/mtrr和/proc/iomem中标识DMA内存?

在/proc/mtrr和/proc/iomem中标识DMA内存?,c,memory,linux-kernel,dma,C,Memory,Linux Kernel,Dma,我想知道是否有一种方法可以识别某些proc文件中用于DMA映射的内存,例如mtrr和iomem,或者通过lspic-vv 在我的/proc/mtrr中,只有一个不可缓存的区域,它几乎指向3.5-4GB的“PCI孔” base=0x0e0000000 ( 3584MB), size= 512MB, count=1: uncachable 通过与/proc/iomem交叉验证,在这个512MB区域中,只有4GB之前的最后21MB没有被PCI总线占用,21MB的内存被pnp/IOAPIC/Rese

我想知道是否有一种方法可以识别某些proc文件中用于DMA映射的内存,例如
mtrr
iomem
,或者通过
lspic-vv

在我的
/proc/mtrr
中,只有一个
不可缓存的
区域,它几乎指向3.5-4GB的“PCI孔”

base=0x0e0000000 ( 3584MB), size=  512MB, count=1: uncachable
通过与
/proc/iomem
交叉验证,在这个512MB区域中,只有4GB之前的最后21MB没有被PCI总线占用,21MB的内存被
pnp/IOAPIC/Reserved
占用

因此,我的问题是:

  • /proc/mtrr
    /proc/iomem
  • 是否有其他地方,例如其他proc文件和命令,我可以用来查看DMA区域
  • 似乎通过向
    /proc/mtrr
    添加行,特权用户可以在运行时更改任何内存的缓存机制。因此,除了DMA必须低于32位(假设没有DAC)这一事实之外,DMA内存分配还有其他特殊要求吗?如果没有进一步的要求,那么我可以用来识别DMA内存的唯一提示就是
    /proc/mtrr
  • DMA(直接内存访问)就是设备访问内存本身的地方(不要求CPU向设备提供数据)。对于DMA的(简化)示例;想象一个随机进程执行一个
    write()
    ,然后它冒出气泡(通过VFS、文件系统、任何RAID层等),直到到达某种磁盘控制器驱动程序;然后,磁盘控制器驱动程序告诉其磁盘控制器“将N个字节从这个物理地址传输到磁盘上的那个位置,并在传输完成后通知我”。大多数设备(磁盘控制器、网卡、视频卡、声卡、USB控制器等)以某种方式使用DMA。在负载下,计算机中的所有设备可能每秒进行数千次传输(通过.DMA),可能分散在所有可用RAM中

    据我所知;
    /proc/
    中没有任何文件可以提供帮助(很可能是因为它变化太快,太频繁,不需要提供任何文件,而且几乎没有理由让任何人想要查看它)

    MTTR基本上是不相关的——它们只控制CPU的缓存,对来自设备的DMA请求没有影响

    /proc/iomem
    也不相关。它只显示设备用于自己寄存器的区域,与RAM无关(因此与DMA无关)

    注1:DMA不必是低32位(例如,大多数PCI设备支持64位DMA/总线主控已经十年或更长时间);对于极少数不支持64位的设备,Linux可以使用IOMMU重新映射它们的请求(因此设备认为它使用的是32位地址,而实际上不支持)


    注2:很久以前有“ISA DMA控制器芯片”。就像ISA总线本身一样;这些限制仅限于物理地址空间的前16个MiB(还有其他限制,例如不支持跨越64 KiB边界的传输)。自从软盘控制器过时以来,这些芯片就没有存在的理由。您可能会有一个
    /proc/dma
    来描述这些(但如果您这样做,它可能只会说“级联”来指示芯片如何连接,而没有设备使用它们)

    谢谢。我试图弄清楚这一点——如果DMA使用不可缓存的内存类型,那么哪个函数保证DMA缓冲区不可缓存?最初我认为这只由MTRR决定,因此我转到/proc/MTRR文件/proc/IOEM不仅包含设备内存映射IO,还包含系统内存,因此它可能还包含一些信息。但后来我发现x86现在使用PAT,所以MTRR在很大程度上并不重要。尽管如此,我还是没有找到什么代码保证DMA缓冲区是UC,例如,从DMA_alloc_coherent()中;设备和RAM之间没有缓存,因此不会缓存DMA访问(所有DMA访问都可以被视为“未缓存”)。当设备发出读或写操作时,CPU/s会看到该请求,并首先将其缓存中的任何修改数据写回RAM,以便设备读取/写入最新版本。注意:严格来说,这并不总是正确的(有些芯片在RAM和其他所有东西之间有一个eDRAM缓存;有些芯片支持新的“直接缓存访问”功能,特殊设备可以将数据直接注入CPU缓存)。@QnA:还请注意(对于PAT);一个CPU可能将一页RAM映射为“写回”,而另一个CPU将同一页RAM映射为“未缓存”;因此,除了从设备进行访问外,还需要相同的“正在缓存的CPU需要写回任何修改的数据,以响应来自非缓存对象的访问”行为。谢谢。我好奇的是RAM和CPU缓存之间的同步,而不是设备和RAM之间有另一个缓存。你好像是说有一些硬件保证。以x86上的PCI为例:1。设备写入RAM后,谁将RAM内容同步到CPU缓存?是DRAM控制器/PCI根复合体/PCI设备/其他设备吗?2.在设备从RAM读取数据之前,谁会将CPU缓存和写缓冲区转储到RAM?@QnA:Erm。太晚之后不需要同步RAM和缓存,因为它在太晚之前(在设备进行读写之前)已经同步。例如,如果PCI设备写入RAM,则CPU被告知将修改后的数据写回RAM,然后PCI设备的写入发生在正确版本的数据上(而不是RAM中过时的数据);然后,如果CPU想在之后再次获取数据,它必须将RAM中的数据恢复到缓存中。