【问题标题】:Identify DMA memory in /proc/mtrr and /proc/iomem?识别 /proc/mtrr 和 /proc/iomem 中的 DMA 内存?
【发布时间】:2020-05-17 13:07:19
【问题描述】:

不知道有没有办法在一些proc文件中识别用于DMA映射的内存,比如mtrriomem,或者通过lspic -vv

在我的/proc/mtrr 中,只有一个uncachable 区域,它似乎指向了 3.5-4GB 的“PCI 孔”,差不多。

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

【问题讨论】:

    标签: c memory linux-kernel dma


    【解决方案1】:

    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/iomem 不仅包含设备内存映射的 IO,还包含系统内存,因此它也可能包含一些信息。但后来我发现 x86 现在使用 PAT,所以 MTRR 基本上并不重要。尽管如此,我还是没有找到保证 DMA 缓冲区是 UC 的代码,例如,来自 dma_alloc_coherent()。
    • @QnA:一般;设备和 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:嗯。在为时已晚之后,什么都不需要同步 RAM 和缓存,因为它在为时已晚之前同步(在设备进行读取或写入之前)。例如。如果 PCI 设备写入 RAM,则 CPU 被告知将修改后的数据写回 RAM,然后 PCI 设备的写入发生在正确版本的数据上(而不是 RAM 中数据的陈旧版本);然后如果 CPU 之后再次需要数据,它必须从 RAM 中取回缓存。
    猜你喜欢
    • 2017-01-06
    • 2013-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-03
    • 1970-01-01
    相关资源
    最近更新 更多