NTB 驱动程序¶
NTB(非透明桥接)是一种 PCI-Express 桥接芯片,它将两个或多个计算机的独立内存系统连接到同一 PCI-Express 结构。现有的 NTB 硬件支持一个常见的功能集:门铃寄存器和内存转换窗口,以及诸如暂存器和消息寄存器之类的非通用功能。暂存寄存器是可从设备两侧访问的读写寄存器,以便对等方可以在固定地址交换少量信息。消息寄存器可用于相同的目的。此外,它们还提供特殊的状态位,以确保信息不会被另一个对等方重写。门铃寄存器提供了一种对等方发送中断事件的方法。内存窗口允许对等内存进行转换的读写访问。
NTB 核心驱动程序 (ntb)¶
NTB 核心驱动程序定义了一个封装通用功能集的 api,并允许对 NTB 功能感兴趣的客户端发现硬件驱动程序支持的 NTB 设备。 此处使用的术语“客户端”是指使用 NTB api 的上层组件。 此处使用的术语“驱动程序”或“硬件驱动程序”是指特定供应商和型号的 NTB 硬件的驱动程序。
NTB 客户端驱动程序¶
NTB 客户端驱动程序应向 NTB 核心驱动程序注册。 注册后,当插入和删除 ntb 硬件或硬件驱动程序时,将适当地调用客户端探测和删除函数。 注册使用 Linux 设备框架,因此对于任何编写过 pci 驱动程序的人来说,它应该会感到很熟悉。
NTB 典型客户端驱动程序实现¶
NTB 的主要目的是在至少两个系统之间共享一些内存空间。因此,NTB 设备功能(如暂存/消息寄存器)主要用于执行正确的内存窗口初始化。通常,NTB API 支持两种类型的内存窗口接口:在本地 ntb 端口上配置的入站转换和在对等 ntb 端口上由对等方配置的出站转换。第一种类型如下图所示
Inbound translation:
Memory: Local NTB Port: Peer NTB Port: Peer MMIO:
____________
| dma-mapped |-ntb_mw_set_trans(addr) |
| memory | _v____________ | ______________
| (addr) |<======| MW xlat addr |<====| MW base addr |<== memory-mapped IO
|------------| |--------------| | |--------------|
因此,第一种类型的内存窗口初始化的典型场景是:1) 分配内存区域,2) 将转换后的地址放入 NTB 配置,3) 以某种方式通知对等设备已执行初始化,4) 对等设备映射相应的出站内存窗口,以便可以访问共享内存区域。
第二种类型的接口,意味着共享窗口由对等设备初始化,如下图所示
Outbound translation:
Memory: Local NTB Port: Peer NTB Port: Peer MMIO:
____________ ______________
| dma-mapped | | | MW base addr |<== memory-mapped IO
| memory | | |--------------|
| (addr) |<===================| MW xlat addr |<-ntb_peer_mw_set_trans(addr)
|------------| | |--------------|
第二种类型接口初始化的典型场景是:1) 分配内存区域,2) 以某种方式将转换后的地址传递给对等设备,3) 对等方将转换后的地址放入 NTB 配置,4) 对等设备映射出站内存窗口,以便可以访问共享内存区域。
正如人们所见,所描述的场景可以组合在一个可移植的算法中。
- 本地设备
为共享窗口分配内存
通过分配区域的转换地址初始化内存窗口(如果不支持本地内存窗口初始化,则可能会失败)
将转换后的地址和内存窗口索引发送到对等设备
- 对等设备
使用从另一个设备检索到的分配的内存区域的地址初始化内存窗口(如果不支持对等内存窗口初始化,则可能会失败)
映射出站内存窗口
根据此方案,NTB 内存窗口 API 可按如下方式使用
- 本地设备
ntb_mw_count(pidx) - 检索可以在本地设备和具有指定索引的端口的对等设备之间为内存窗口分配的内存范围的数量。
ntb_get_align(pidx, midx) - 检索限制共享内存区域对齐和大小的参数。然后可以正确分配内存。
按照 2) 中检索的限制分配物理连续的内存区域。
ntb_mw_set_trans(pidx, midx) - 尝试为定义的对等设备设置具有指定索引的内存窗口的转换地址(如果不支持本地转换地址设置,则可能会失败)
使用暂存器或消息寄存器等,将转换后的基址(通常与内存窗口号一起)发送到对等设备。
- 对等设备
ntb_peer_mw_set_trans(pidx, midx) - 尝试为指定的内存窗口设置从其他设备(与 pidx 相关)接收到的转换地址。如果检索到的地址例如超过最大可能地址或未正确对齐,则可能会失败。
ntb_peer_mw_get_addr(widx) - 检索 MMIO 地址以映射内存窗口,以便访问共享内存。
还值得注意的是,方法 ntb_mw_count(pidx) 应返回与对等方上端口索引为 pidx 的 ntb_peer_mw_count() 相同的值。
NTB 传输客户端 (ntb_transport) 和 NTB 网络设备 (ntb_netdev)¶
NTB 的主要客户端是传输客户端,与 NTB 网络设备一起使用。 这些驱动程序协同工作以在 ntb 上创建与对等方的逻辑链接,以交换网络数据包。 传输客户端建立与对等方的逻辑链接,并创建队列对以交换消息和数据。 然后,NTB 网络设备使用传输队列对创建一个以太网设备。 网络数据在套接字缓冲区和传输队列对缓冲区之间复制。 传输客户端可能用于除网络设备之外的其他用途,但尚未编写其他应用程序。
NTB Ping Pong 测试客户端 (ntb_pingpong)¶
Ping Pong 测试客户端用作演示,以练习 NTB 硬件的门铃和暂存寄存器,并作为简单的 NTB 客户端的示例。 Ping Pong 在启动时启用链接,等待 NTB 链接启动,然后继续读取和写入 NTB 的门铃暂存寄存器。 对等方使用门铃位的位掩码相互中断,该位掩码在每一轮中移动一位,以测试多个门铃位和中断向量的行为。 Ping Pong 驱动程序还会读取第一个本地暂存器,并将值加一写入第一个对等暂存器,在每次写入对等门铃寄存器之前。
模块参数
- unsafe - 某些硬件在暂存器和门铃方面存在已知问题
寄存器。 默认情况下,Ping Pong 不会尝试练习此类硬件。 您可以通过设置 unsafe=1,自行承担风险来覆盖此行为。
- delay_ms - 指定接收门铃之间的延迟
中断事件并设置对等方门铃寄存器以进行下一轮操作。
- init_db - 指定门铃位以开始新的一系列轮询。一旦所有的门铃位都被移出范围,
新的系列轮询就开始了。
- dyndbg - 建议在加载此模块时指定 dyndbg=+p,然后
在控制台上观察调试输出。
NTB 工具测试客户端 (ntb_tool)¶
该工具测试客户端主要用于调试 NTB 硬件和驱动程序。该工具通过 debugfs 提供访问权限,用于读取、设置和清除 NTB 门铃,以及读取和写入暂存器。
该工具目前没有任何模块参数。
Debugfs 文件
- debugfs/ntb_tool/hw/
将为该工具探测的每个 NTB 设备在 debugfs 中创建一个目录。此目录在下面缩写为hw。
- hw/db
此文件用于读取、设置和清除本地门铃。并非所有硬件都可能支持所有操作。要读取门铃,请读取该文件。要设置门铃,请写入 s 后跟要设置的位(例如:echo 's 0x0101' > db)。要清除门铃,请写入 c 后跟要清除的位。
- hw/mask
此文件用于读取、设置和清除本地门铃掩码。有关详细信息,请参阅 db。
- hw/peer_db
此文件用于读取、设置和清除对等方门铃。有关详细信息,请参阅 db。
- hw/peer_mask
此文件用于读取、设置和清除对等方门铃掩码。有关详细信息,请参阅 db。
- hw/spad
此文件用于读取和写入本地暂存器。要读取所有暂存器的值,请读取该文件。要写入值,请写入一系列暂存器编号和值对(例如:echo '4 0x123 7 0xabc' > spad # 将暂存器 4 和 7 分别设置为 0x123 和 0xabc)。
- hw/peer_spad
此文件用于读取和写入对等方暂存器。有关详细信息,请参阅 spad。
NTB MSI 测试客户端 (ntb_msi_test)¶
MSI 测试客户端用于测试和调试 MSI 库,该库允许跨 NTB 内存窗口传递 MSI 中断。测试客户端通过 debugfs 文件系统进行交互。
- debugfs/ntb_msi_test/hw/
将为 msi 测试探测的每个 NTB 设备在 debugfs 中创建一个目录。此目录在下面缩写为hw。
- hw/port
此文件描述本地端口号
- hw/irq*_occurrences
每个中断都存在一个 occurrences 文件,读取该文件时,会返回中断被触发的次数。
- hw/peer*/port
此文件描述每个对等方的端口号
- hw/peer*/count
此文件描述可以在每个对等方上触发的中断数
- hw/peer*/trigger
写入一个中断号(任何小于 count 中指定的值的数字)将触发指定对等方上的中断。该对等方的中断的 occurrences 文件应递增。
NTB 硬件驱动程序¶
NTB 硬件驱动程序应向 NTB 核心驱动程序注册设备。注册后,将调用客户端的探测和删除函数。
NTB Intel 硬件驱动程序 (ntb_hw_intel)¶
Intel 硬件驱动程序支持 Xeon 和 Atom CPU 上的 NTB。
模块参数
- b2b_mw_idx
如果需要通过内存窗口访问对等方 ntb,则使用此内存窗口访问对等方 ntb。零或正值从第一个 mw idx 开始,负值从最后一个 mw idx 开始。双方都必须在此处设置相同的值!默认值为-1。
- b2b_mw_share
如果需要通过内存窗口访问对等方 ntb,并且如果内存窗口足够大,仍然允许客户端使用内存窗口的后半部分来将地址转换为对等方。
- xeon_b2b_usd_bar2_addr64
如果在 Xeon 硬件上使用 B2B 拓扑,请在 NTB 设备之间的总线上,使用 BAR2 窗口的此 64 位地址(位于链路的上游侧)。
xeon_b2b_usd_bar4_addr64 - 请参阅 xeon_b2b_bar2_addr64。
xeon_b2b_usd_bar4_addr32 - 请参阅 xeon_b2b_bar2_addr64。
xeon_b2b_usd_bar5_addr32 - 请参阅 xeon_b2b_bar2_addr64。
xeon_b2b_dsd_bar2_addr64 - 请参阅 xeon_b2b_bar2_addr64。
xeon_b2b_dsd_bar4_addr64 - 请参阅 xeon_b2b_bar2_addr64。
xeon_b2b_dsd_bar4_addr32 - 请参阅 xeon_b2b_bar2_addr64。
xeon_b2b_dsd_bar5_addr32 - 请参阅 xeon_b2b_bar2_addr64。