资讯详情

资讯详情

第 0 篇 经 DMA 的一帧数据传输路径:本专栏讨论的 15 个核心问题

本文为“从硅到用户态的 DMA 全景”专栏的开篇。本文不对具体问题作出解答而是梳理全专栏需要讨论的问题并说明各问题之间的层次关系。1. 场景设定常见的 DMA 资料通常以定义作为起点DMADirect Memory Access直接内存访问是一种允许外设绕过 CPU、直接读写系统内存的机制。该定义概括了 DMA 的基本特征但未涉及一次实际 DMA 传输的具体过程包括数据的来源与去向、地址由谁翻译、访问受何种机制保护也未说明这一路径为何在 cache 一致性、IOMMU、跨平台移植、异构内存等环节频繁引发问题。因此本专栏不以定义为起点而以一个贯穿全程的 DMA 具体场景作为分析对象一台服务器上的网卡接收一帧数据需将其传送至主机内存供应用处理随后应用将一帧待发送数据交由网卡发出。整个过程数据不经 CPU 逐字节复制而由硬件直接在内存与设备之间传输。该场景涉及的网卡、内存、CPU、cache、IOMMU、驱动与应用等组件将在后续各篇中逐步登台。在专栏的第五册同一传输过程将置于 GPU 与加速器构成的异构平台中重新分析当系统中存在多种内存、设备拥有独立显存时该路径的复杂度将显著增加。下文以该传输过程为线索按照由硬件到软件、由内核到用户态的顺序逐一列出各环节涉及的关键问题。2. 传输路径上的 15 个问题图 1 给出了接收方向的完整处理流程。纵向为时间顺序分为准备、接收、处理与交付三个阶段横向为参与该过程的各方泳道。右侧标注了各步骤涉及的问题颜色表示问题所属的层次。发送方向的流程与之对称数据由内存流向网卡所涉及的问题基本相同。问题的编号与专栏篇目顺序一致即由硬件原理、IOMMU、内核抽象至用户态驱动逐层展开后一问题通常以前一问题为前提。因此问题编号与图中步骤的先后顺序并不完全一致。下文按编号逐一说明。图 1网卡接收数据流程及问题列表2.1 数据传输的执行者网卡接收到一帧数据后首先将其暂存于片上包缓冲区RX FIFO。该缓冲区容量有限通常为数百 KB 至数 MB在 100Gbps 线速下数十微秒即可写满而 CPU 通过 MMIO 读取设备内存时每次访问均需完成一次 PCIe 往返延迟为微秒量级且通常不可缓存。因此片上缓冲区仅承担暂存职能数据帧须由网卡主动传送至主机内存再由协议栈与应用处理。该传送过程并非由 CPU 通过 load/store 指令逐条完成而是由网卡内部独立的硬件引擎发起。需要明确的是该引擎的实体形态、在芯片中的位置以及其与 CPU 之间的分工。问题 1CPU 为何将数据搬运任务交由专用硬件完成承担该任务的 DMA 引擎具体是什么2.2 接收缓冲区的地址DMA 引擎对主机内存的访问以地址为唯一依据并不感知操作系统层面的内存管理语义。为此驱动需预先分配接收缓冲区并将其地址写入描述符环告知网卡。由此引出的问题是CPU 所使用的地址虚拟地址与物理地址与设备所使用的地址是否相同。问题 2设备发出的地址与 CPU 视角下的物理地址是否为同一概念2.3 内存数据与 CPU 读取结果的不一致网卡依据描述符中的地址将数据帧写入内存随后由 CPU 读取。该环节是整条路径中最隐蔽、后果最严重的一处网卡已将新数据写入内存CPU 读取该地址时却可能获得旧值反之CPU 写入待发送数据后网卡读出的也可能是旧值。问题的根源不在内存本身而在于 CPU 与设备访问内存的方式不同CPU 经由 cache 访问设备通常直接访问内存。问题 3数据已写入内存另一方为何仍可能读到旧值cache 一致性问题的根源是什么2.4 一致性行为的平台差异上述一致性问题在 x86 服务器上通常不会出现但同一驱动移植至部分 ARM 或嵌入式平台后可能出现偶发的数据损坏。这表明一致性在某些平台上由硬件自动维护而在另一些平台上需要软件显式维护。问题 4同一代码为何在 x86 平台上运行正常在其他平台上却出现数据错误硬件一致性机制具体承担了哪些职责2.5 缓冲区的物理布局约束除一致性外接收缓冲区本身也受设备能力的约束。回到驱动分配缓冲区的环节部分设备要求目标内存物理连续部分设备仅能访问低地址空间。而在虚拟地址空间中连续的缓冲区其物理页往往是分散的。当设备无法直接访问缓冲区所在的物理地址时传统的应对方式是经由低地址区域的中转缓冲区进行复制。问题 5设备为何对内存的物理布局存在约束物理连续性要求与地址位宽限制分别源于何处2.6 IOMMU 的地址翻译与隔离如何解决问题 2 与问题 5 呢这里就引出了IOMMU。IOMMU 位于设备与内存之间对设备发出的每一个地址进行翻译并将设备的访问范围限制在授权区域内。借助这一机制问题 2 和 5 的物理连续性、地址位宽与越界防护三个看似独立的问题得以统一解决。问题 6IOMMU 如何同时解决物理连续性、寻址范围与设备隔离三个问题其内部的地址翻译过程是怎样的2.7 IOMMU 映射的性能开销IOMMU 的地址翻译存在额外开销。IOMMU 维护独立的页表与 TLBIOTLB每次建立或拆除映射均需更新页表并失效相应缓存。在高频收发的数据面场景中这部分开销可能成为性能瓶颈。问题 7IOMMU 地址翻译存在哪些隐性开销频繁的 map/unmap 操作为何会成为性能瓶颈2.8 一致性映射与流式映射以上问题均由硬件机制决定驱动需通过内核提供的 DMA 映射接口加以应对。这里就进入了 dma 的驱动接口所以理解了上面的硬件设计就可以很好地理解和记忆这些驱动接口。针对问题 3、4 所述的一致性问题内核提供两类 DMA 映射方式一类在分配后即可由 CPU 与设备随时访问无需显式同步另一类效率更高但要求驱动自行管理同步时机。两者的区别不在于接口用法而在于对一致性责任归属的不同约定。问题 8dma_alloc_coherent与dma_map_single的本质区别是什么内核为何提供两种映射契约2.9 缓冲区所有权的交接采用流式映射时由于一致性并非在所有平台上自动成立驱动须显式声明缓冲区当前归设备使用还是归 CPU 使用在网卡写入之前将所有权交给设备在 CPU 读取之前将所有权收回。这一所有权交接约定是流式 DMA 映射的核心遗漏任何一次交接均可能引入偶发性错误。问题 9dma_sync_*系列同步操作的作用是什么CPU 与设备之间如何交接缓冲区所有权2.10 分散内存的统一映射问题 5 所述的物理分散在映射接口层面同样需要处理若缓冲区在物理上由多个分散片段组成是否需要逐段交由设备处理。内核通过 scatter-gather 机制将多段内存组织为一个整体进行映射在启用 IOMMU 的系统中多段物理内存还可借助问题 6 所述的地址翻译在设备视角下呈现为一段连续地址。问题 10物理上分散的内存为何能以连续地址的形式提供给设备dma_map_sg完成了哪些工作2.11 DMA 掩码与反弹缓冲问题 5 所述的地址位宽限制在映射接口层面体现为 DMA 掩码。驱动在初始化阶段需声明设备可寻址的地址范围若设备的寻址能力不足以覆盖目标内存内核将启用中转缓冲区bounce buffer即 SWIOTLB先完成一次数据复制再交由设备访问。该过程不产生任何错误提示仅表现为性能下降。问题 11驱动为何需要声明 DMA 掩码掩码设置不当会引入何种性能代价2.12 映射接口的后端分发至此同一次映射请求已出现三种可能的处理方式直接映射、经由 IOMMU 翻译问题 6以及经由 SWIOTLB 中转问题 11。驱动调用的是同一组 DMA 映射接口具体实现由分层的dma_map_ops根据设备属性选择。问题 12一次 DMA 映射调用如何被分发至 direct、iommu、swiotlb 等不同后端2.13 跨设备的缓冲区共享以上讨论限于网卡与 CPU 之间。实际系统中数据通常需要经过多个设备处理。例如一帧图像可能依次经过相机采集、GPU 处理与编码器压缩若每一步均进行数据复制则无法实现零拷贝。dma-buf 机制使同一缓冲区能够在多个驱动与设备之间共享与同步。问题 13相机、GPU、编码器等不同设备如何以零拷贝方式共享同一块内存2.14 用户态 DMA 的安全边界以上各环节中DMA 均由内核驱动发起。而在高性能场景中应用程序常需绕过内核、直接驱动设备收发数据。此时必须明确用户态进程直接控制硬件读写内存时系统的安全性由何种机制保障。答案再次指向问题 6 所述的 IOMMU若缺少其提供的隔离用户态发起的 DMA 将不受任何访问范围约束。问题 14用户态进程为何能够被允许直接发起 DMA其安全边界由何种机制保障2.15 零拷贝的不同实现路线将 DMA 能力开放给应用程序后零拷贝存在多种实现形态完全绕过内核的方案如 DPDK 数据面、在内核协作下完成的方案如 io_uring 注册缓冲区以及跨主机直接访问远端内存的方案如 RDMA。各方案在性能、隔离性与通用性之间做出了不同的权衡。问题 15内核旁路、内核协作与跨主机直接访问三类零拷贝方案有何区别各自以何种代价换取性能3. 问题的层次划分将上述 15 个问题按所属层次归类即构成本专栏的整体结构也对应数据在传输过程中经过的各个层次。其中问题 1–13 与第 1–13 篇一一对应问题 14、15 分别对应第四册的前后两部分层次对应问题对应篇目目标认知硬件原理问题 1–5第 1–5 篇DMA 在硬件层面的执行方式以及一致性问题的成因IOMMU问题 6–7第 6–7 篇地址翻译与设备隔离的基础机制内核抽象问题 8–13第 8–13 篇dma-mapping 接口的设计原则用户态驱动问题 14–15第 14–18 篇将 DMA 能力安全地开放给应用程序异构计算全部问题第 19–23 篇多种内存并存时传输路径的变化调试与性能全部问题第 24–25 篇故障定位方法与性能、可移植性检查其中有一条主线需要预先说明来引起你的重视即一致性。该主题首先出现于问题 3cache 与设备视角的不一致在问题 4 中延伸至硬件平台差异在问题 8、9 中体现为驱动代码中的映射契约与所有权交接约定在问题 13 中扩展至跨设备共享并在异构计算一册中演变为显存与系统内存之间的按需迁移与显式失效。一致性贯穿整条传输路径是本专栏持续关注的核心主题。4. 异构场景下的延伸本专栏的讨论范围不局限于单机、单一内存的系统。在第五册中同一传输过程将置于 GPU 与加速器构成的异构场景中重新分析数据不再仅在系统内存中流动而需要在系统内存与显存之间迁移设备不再仅被动接收地址在访问尚未驻留的页面时会主动触发缺页一致性的维护也不再局限于 cache 刷新而涉及粗粒度一致性模型以及不同架构之间的门控差异。届时本篇列出的 15 个问题均将以更复杂的形式再次出现前序各册的内容将为其分析提供必要基础。5. 阅读建议顺序阅读各问题之间存在递进关系硬件原理是内核抽象的基础内核抽象又是用户态驱动的基础。按顺序阅读有助于建立完整的知识体系。按需阅读每一篇均围绕独立的问题展开。若仅关注特定问题例如驱动移植后出现数据损坏的原因可直接阅读相应篇目。结合场景阅读每读完一篇可对照本篇给出的传输路径确认该知识点所处的环节及其解答的问题。下一篇将回答问题 1即 CPU 为何将数据搬运任务交由专用硬件完成。文中将分析 DMA 出现之前 CPU 以程序化 I/OPIO方式逐字传输数据的过程以及该方式的性能代价。系列导航下一篇《第 1 篇 从 PIO 到 DMACPU 为何将数据搬运交由专用硬件》
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →