识别 /proc/mtrr 和 /proc/iomem 中的 DMA 内存?

Identify DMA memory in /proc/mtrr and /proc/iomem?

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

我的/proc/mtrr里面只有一个uncachable区域,好像是指向'PCI hole'3.5-4GB,差不多。

base=0x0e0000000 ( 3584MB), size=  512MB, count=1: uncachable

通过与 /proc/iomem 的交叉验证,在这个 512MB 的区域中,只有 4GB 之前的最后 21MB 没有被 PCI 总线占用,而那 21MB 的条带被诸如 pnp/IOAPIC/Reserved 之类的东西占用。

所以我的问题是:

  1. /proc/mtrr/proc/iomem 中 DMA 区域的签名是什么
  2. 是否有其他地方,例如其他 proc 文件和命令,我可以使用它来查看 DMA 区域?
  3. 似乎通过向 /proc/mtrr 添加行,特权用户可以在运行时更改任何内存的缓存机制。那么除了DMA必须低于32位(假设没有DAC)之外,DMA内存分配还有其他特殊要求吗?如果没有进一步的要求,那么我可以用来识别 DMA 内存的唯一提示可能是 /proc/mtrr?

DMA(直接内存访问)就是设备访问内存本身的地方(不需要 CPU 将数据提供给设备)。对于 DMA 的(简化)示例;想象一个随机进程执行 write(),并且它向上冒泡(通过 VFS、通过文件系统、通过任何 RAID 层等),直到它到达某种磁盘控制器驱动程序;然后磁盘控制器驱动程序告诉它的磁盘控制器"transfer N bytes from this physical address to that place on the disk and let me know when the transfer has been done"。大多数设备(磁盘控制器、网卡、视频卡、声卡、USB 控制器……)都以某种方式使用 DMA。在负载下,您计算机中的所有设备可能每秒进行数千次传输(通过 DMA),可能分散在所有可用的 RAM 中。

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

MTTR 大多无关紧要 - 它们仅控制 CPU 的缓存,对来自设备的 DMA 请求没有影响。

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

注 1:DMA 不必在低 32 位(例如,大多数 PCI 设备支持 64 位 DMA/bus mastering 已有十年或更长时间);对于不支持 64 位的稀有设备,Linux 可以使用 IOMMU 来重新映射它们的请求(因此设备认为它使用的是 32 位地址,但实际上不是)。

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