高性能网络 — PCIe 总线标准 前文列表 《高性能网络 — SmartNIC、DPU 设备演进与运行原理》 目录 计算机总线系统PCIe 总线PCIe 总线的传输速率PCIe 总线的架构PCIe 外设PCIe 设备的枚举过程PCIe 设备的 BDF 编号PCIe 设备的 BAR 地址Linux 上的 PCIe 设备查看 PCIe 设备的 BDF查看 PCIe 设备的 Vendor 和 Device查看 PCIe 设备的详细信息 计算机总线系统 总线系统(Bus System),用于完成主机(CPU + Main Memory)和 I/O 外设(网卡、磁盘)等内部组件之间的通信。
从功能实现上,可以分为 3 种总线类型:数据总线:用于在 CPU 与 Main Memory 或 I/O 设备之间传输数据。地址总线:用于在 CPU 与 Main Memory 或 I/O 设备之间传输地址信息。控制总线:用于在 CPU 与 Main Memory 或 I/O 设备之间传输控制信号。 从系统模块的角度,总线系统主要由 2 大部分组成:CPU 总线,又称为 FSB(Front Side Bus,前端总线)。PCI/PCIe 总线。
PCIe 总线 PCIe(Peripheral Component Interconnect Express,快速外设组件互连标准)是一种高速总线技术,用于统一连接 NIC、Disk、GPU 等多种类型的 I/O 外设。 PCIe 总线的传输速率
PCIe 使用 GT/s(Giga transmission per Second)作为传输速率的计量单位,区别于网络带宽的计量单位 Gbps(Giga bits per second)。因为 PCIe 协议具有 “行代码比“ 开销,根据不同的编码方案,会占用一定量的原始信道带宽。 所以,PCIe 带宽吞吐量的计算公式为:带宽 = 传输速率 x 行代码比。例如:PCIe 2.0 采用的编码方案是 8b/10b,含义是 10bits 数据里面,有 2bits 是额外的开销,实际上只传递了 8bits 的实际数据。所以,PCIe 2.0 每一条 Lane 的带宽为 5GT/s x 8b / 10b = 500MB/s,那么 PCIe 2.8 x 8 Lane 设备的总带宽就是 500MB/s x 8 = 4GB/s。 通常我们只需要实际的吞吐量数据,只是需要区分两者的差别。另外,PCIe 协议支持向前兼容的特性,如果设备支持 PCIe 4.0,但计算机主板支持只支持 PCIe 3.0,那么系统就只能以 3.0 的传输速率运行。 PCIe 总线的架构 相较于更早前的 PCI Bus 采用的共享并行互联架构,所有 I/O 设备共用一个总线带宽,导致整体性能不高。PCIe Bus 则采用了串行互联架构,以点对点的形式进行数据传输,也就是说每个 PCIe Devices 都有自己的专用连接,可以独享带宽,而不必向共享总线竞争带宽。
具体而言,PCIe 总线架构由以下几个部分组成:PCIe Root Complex(RC,根聚合体):位于主板之上,通过 CPU Bus 与 CPU 和 Main Memory 互联,充当 CPU、Main Memory、PCIe Bus 之间通信的枢纽,并实现各类外设总线的聚合。PCIe Switch:作为 PCle Hub and Switch,连接 PCIe RC 和多个 PCIe Devices,使得 PCIe Bus 具有良好的扩展性。PCIe Endpoint:接入到 PCIe Bus 上的 PCIe Device,可以分为 2 种类型:Lagacy PCl-E Endpoint:指兼容 PCIe 标准的 PCI / PCI-X Device。Native PCl-E Endpoint:指标准的 PCle Device。PCI/PCI-X Bridge:作为 PCI/PCI-X Bus 和 PCIe Bus 之间的桥接,以此支持标准的 PCI/PCI-X Devices。
PCIe 总线的工作原理如下:PCIe Root Complex 发送一个 TLP(Transaction Layer Packet,事务层数据包)到 PCIe Bus。PCIe Switch 接收 TLP 并进行路由,将 TLP 转发到 Target PCIe Device。PCIe Device 接收到 TLP 后返回 TLP Response。PCIe Switch 接收 TLP Response 后返回给 PCIe Root Complex。 PCIe 外设 PCIe 设备的接口类型:
PCIe 设备的体积类型:LP(半高)FH(全高)HL(半长)FL(全长)SW(单宽)DW(双宽)PCIe 设备的插槽:PCIe Bus 支持对 PCI/PCI-X Bus 的软件兼容,但主板上的接口插槽却不兼容,因为 PCIe 是串行接口,针数会更少,插槽会更短。
PCIe 设备的枚举过程 PCIe Bus 是一个树状结构,所以 PCIe Devices 的枚举算法采用了深度优先遍历算法,即:对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次。主机起电后,操作系统首先扫描 Bus0(Root Complex 与 Host Bridge 相连的 PCIe Bus 定为 Bus0)。随后发现 Bridge1,将 Bridge1 下游的 PCIe Bus 定为 Bus1。初始化 Bridge 1 的配置空间,并 Bridge1 的 Primary Bus Number 和 Secondary Bus Number 寄存器分别设置成 0 和 1,表明 Bridge1 的上游总线是 Bus0,下游总线是 Bus1。由于还无法确定 Bridge1 下挂载设备的具体情况,系统先暂时将 Subordinate Bus Number 设为 0xFF。
操作系统开始扫描 Bus1。随后发现 Bridge3,并识别为一个 PCIe Switch 类型。系统将 Bridge3 下游的 PCIe Bus 定为 Bus 2,并将 Bridge3 的 Primary Bus Number 和 Secondary Bus Number 寄存器分别设置成 1 和 2。一样暂时把 Bridge3 的 Subordinate Bus Number 设为 0xFF。
操作系统继续扫描 Bus2。随后发现 Bridge4。继续扫描,随后发现 Bridge4 下面挂载了 NVMe SSD 设备。将 Bridge4 下游的 PCIe Bus 定为 Bus3,并将 Bridge4 的 Primary Bus Number 和 Secondary Bus Number 寄存器分别设置成 2 和 3。另外,因为 Bus3 下游是 PCIe Endpoint,不会再有下游总线了,因此 Bridge4 的 Subordinate Bus Number 的值可以确定为 3。
完成 Bus3 的扫描后,操作系统返回到 Bus2 继续扫描,随后发现 Bridge5。继续扫描,随后发现 Bridge5 下面挂载的 NIC 设备。将 Bridge5 下游的 PCIe Bus 设置为 Bus4,并将 Bridge5 的 Primary Bus Number 和 Secondary Bus Number 寄存器分别设置成 2 和 4。另外,同样因为 Bus4 上挂在的是 PCIe Endpoint,所以 Bridge5 的 Subordinate Bus Number 的值可以确定为 4。
除了 Bridge4 和 Bridge5 以外,Bus2 下面已经遍历完毕,因此返回到 Bridge3。因为 Bus4 是挂载在 Bridge3 下游的最后一个 Bus Number,所以将 Bridge3 的 Subordinate Bus Number 设置为 4。Bridge3 的下游设备都已经扫描完毕,继续返回到 Bridge1,同样将 Bridge1 的 Subordinate Bus Number 设置为 4。
系统返回到 Bus0 继续扫描,会发现 Bridge2,将 Bridge2 下游的 PCIe Bus 定为 Bus5。并将 Bridge2 的 Primary Bus Number 和 Secondary Bus Number 寄存器分别设置成 0 和 5。由于 Graphics Card 也是 PCIe Endpoint,因此 Bridge2 的 Subordinate Bus Number 的值可以确定为 5。 至此,系统完成了对 PCIe Bus 的扫描,将 PCIe Devices 都枚举了出来,操作系统通过这一过程获得了一个完整的 PCIe 设备拓扑结构。
PCIe 设备的 BDF 编号 CPU 要访问一个 PCIe Device 就必须要知道它的总线编号。 PCIe 标准支持在一台 Host 上创建最多 256 个 PCIe Bus,每条 Bus 最多可以支持 32 个 PCIe Device,每个 Device 最多可以支持 8 个 Functions。所以 PCIe 设备的总线编号由 Bus Number(范围是 0~255)、Device Number(范围是 0~31)、Function Number(范围是 0~7)这 3 个部分组成,简称 BDF。 例如:BDF 0000:01:00.0 表示位于 Bus0、Device1、Func0 的 PCIe 设备。
PCIe 设备的 BAR 地址 CPU 除了需要支持 PCIe Device 得 BDF 之外,还需要从 PCIe Device 的 BAR(Base Address Register,基地址寄存器)知道它所拥有的内存空间的地址范围。Device 的 Driver 需要通过 “基地址+寄存器偏移量“ 的方式来访问 Device 的内存空间并完成相应的配置操作。 下图是一个 PCIe Device 的内存配置空间,具有 6 个 BARs,分布在 0x0010 ~ 0x0028 这 24Bytes 中。在操作系统启动时,就会将这些 BARs 完成解析,并以文件系统的方式供用户态 Application 读取。
更进一步的,PCIe Device 会根据不同的目录将这 6 个 BARs 划分为不同的 Region,以 Intel 82599 网卡为例子。其拥有的 6 个 BAR 被分成了 3 块 Regions,各占 64bits:Memory BAR:指向 Main Memory 的一个地址,表示数据存储空间,对应 Device Memory。支持进行 mmap() 映射,如果 Application 希望操作 PCIe 设备,就必须 mmap() 这个地址空间。I/O BAR:指向 Main Memory 的一个地址,表示 I/O 空间,对应 Device Register。Application 需要通过专门的操作接口来进行读写。MSI-X BAR:指向 Main Memory 的一个地址,表示 MSI-X 空间。用来配置 MSI-X 中断向量。
在有了 Memory BAR 和 I/O BAR 之后,CPU 就可以通过 2 种不同的方式来访问 Device 了。其中 Memory BAR 是必须的,而 IO BAR 是可选的。通过 I/O 空间,结合专用的 CPU 指令进行访问。例如:in、out 指令。Intel x86 CPU 的 in、out 的语法如下: 通过 Memory 空间,进行数据读写,实现上更加容易。
下面以 Memory BAR 为例,介绍 Application 访问 Device 的流程。PCIe Device 的 Memory 空间关联到 PF Memory,存放的是 PF 的控制与状态信息。以 NVMe 为例,对 NVMe 的控制以及其工作状态都可以通过访问它的 Memory 空间来实现。 NVMe 命令下发的基本操作是:Host 写 doorbell 寄存器,此时使用 PCIe Memory 写请求。如下图所示,Host 发出一个 MWr(Memory Write)请求,该请求经过 PCIe Switch 到达要访问的 NVMe SSD 设备。
NVMe 读取命令操作,这个请求会被 PCIe Endpoint 接收并执行。如下图所示,此时 NVMe SSD 作为请求者,发出一个 MRd(Memory Read)请求,该请求经过 PCIe Switch 到达 Host CPU。Host CPU 作为完成者会返回一个 CplD(事务完成包),将访问结果返回给 NVMe SSD。
同样,NVMe 的其他操作都是通过 PCIe Memory 访问的方式来进行的。 Linux 上的 PCIe 设备 如下图,查看 Linux 操作系统上的一个 PCIe 设备,具有以下文件:config:设备的配置空间,二进制,可读写。device:设备的 Device ID,只读。vendor:设备的 Vendor ID,只读。driver:设备驱动程序的目录。enable:设备是否正常使能,可读写;irq:设备分到的中断号,只读;local_cpulist:和设备处于同一个 NUMA Node 的 CPU 清单,用于实现 NUMA 亲和性。local_cpu:和 local_cpulist 的作用一样,以掩码的方式给出。numa_node:设备所属的 NUMA node,只读。resource:设备的 BARs 记录,只读。resource0..N:某个 BAR 空间,二进制,只读。sriov_numfs:设备的 VFs 数量。sriov_totalvfs:与 sriov_numfs 作用相同。subsystem_device:PCIe 子系统设备 ID,只读。subsystem_vendor:PCIe 子系统厂商 ID,只读。
查看 PCIe 设备的 BDF 下图黄色方框中的 PCIe 设备是 Bejing Starblaze Technology Co., LTD. 推出的 STAR1000 系列 NVMe SSD 设备,其中 9d32 是 Starblaze 在 PCI-SIG 组织的注册码,1000 是设备系列号。 STAR1000 的 BDF 分别为 0x3C、0x00、0x0,即:3C:00.0,与之对应的上游端口是 00:1d.0。
查看 PCIe 设备的 Vendor 和 Device 下图可以看到一个 NVMe Controller 的详细信息:Vendor ID:供应商识别字段,由 PCI SIG 分配。Device ID:设备识别字段,由供应商分配。Class Code:表示这是一个 NVMe SSD 设备。First Capability Pointer:指向 Device Capability 的入口,从 0x40 地址开始依次是 Power management、MSI 中断、链路控制与状态、MSI-X 中断等特性组。
查看 PCIe 设备的详细信息 下图中展示了指定 PCIe 设备的详细信息。其中可以看见该设备的 Memory BAR 空间,一段的大小是 1MB,另一段的大小是 256KB。系统可以通过 Memory 空间访问设备。
- END – 关于 “云物互联” : 欢迎 “云物互联” ,我们专注于云计算、云原生、SDN/NFV、边缘计算及 5G 网络技术的发展及应用。热爱开源,拥抱开源! 技术即沟通 化云为雨,落地成林
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/57110.html