PCIe BAR 深入解析:从设备地址窗口到 DMA 与 GPUDirect Storage

在操作系统驱动、高性能网卡、NVMe SSD 和 GPU 系统中,经常会同时看到 BAR、MMIO、DMA、IOMMU、peer-to-peer DMA、GPUDirect RDMA 和 GPUDirect Storage 等概念。这些名词都与“设备怎样通过 PCIe 交换控制信息和数据”有关,但它们处在不同层次。 最简洁的理解是: BAR:让 CPU 能够定位并访问 PCIe 设备中的寄存器或显存窗口 DMA:让 PCIe 设备能够主动读取或写入系统内存 P2P DMA:让一个 PCIe 设备直接访问另一个 PCIe 设备暴露的地址空间 GDS:利用 DMA、GPU 内存映射和驱动协作,让存储数据尽量直接进入 GPU 显存 本文从 PCIe 地址空间和事务模型出发,解释 BAR 是如何分配和映射的,驱动为什么通过 BAR 下发命令,DMA 地址为什么不能简单等同于物理地址,以及 GPUDirect Storage 如何把这些机制组合成一条高性能数据路径。 一、先建立 PCIe 系统视图 一个典型服务器的 PCIe 拓扑如下: CPU │ Memory Controller │ Host RAM │ Root Complex ┌──────┴──────┐ │ │ PCIe Switch PCIe Endpoint ┌────┴────┐ GPU │ │ NVMe SSD NIC CPU 和内存构成主机侧。Root Complex 把 CPU/内存系统连接到 PCIe fabric。NVMe、网卡和 GPU 通常是 Endpoint。PCIe Switch 用于扩展端口和转发事务。 ...

2026年8月21日 · 10 分钟 · Hellokitty

nvidia-fs 源码阅读(二):GPU 内存注册、影子页与 DMA 映射

上一篇从 nvfs_init()、字符设备和 ioctl 看到了 nvidia-fs 的外部形态。本文进入 GDS direct path 的核心:怎样把用户分配的 GPU virtual address 变成存储设备能够 DMA 的地址,同时又让 Linux 文件 I/O 栈能够携带它。 阅读版本仍为 NVIDIA gds-nvidia-fs: commit: 328d1d8cce1175c013720985c30e123e9a35242c GDS_VERSION: 2.29.4 一、问题本质 普通块 I/O 最终围绕 bio_vec、struct page、scatterlist 和 DMA mapping 展开。但 cudaMalloc 得到的是 GPU 虚拟地址,对 Linux 页缓存和块层来说,它并不是普通 CPU 内存页。 驱动需要解决三次“翻译”: GPU virtual address -> NVIDIA P2P page table 中的 GPU physical pages -> Linux I/O 栈可携带的影子 struct page -> 某个存储 PCIe 设备可使用的 DMA address 三个地址空间不能混为一谈: ...

2026年8月21日 · 4 分钟 · Hellokitty