英语

OpenCAPI (开放相干加速器处理器接口)

OpenCAPI 是处理器和加速器之间的接口。它的目标是低延迟和高带宽。该规范由 OpenCAPI 联盟开发。

它允许加速器(可以是 FPGA、ASIC 等)使用虚拟地址相干地访问主机内存。OpenCAPI 设备还可以托管自己的内存,可以从主机访问。

OpenCAPI 在 Linux 中被称为“ocxl”,是“cxl”(用于 powerpc 的 IBM CAPI 接口的驱动程序)的开放、与处理器无关的演变,之所以这样命名是为了避免与 ISDN CAPI 子系统混淆。

高层视图

OpenCAPI 定义了一个数据链路层 (DL) 和事务层 (TL),在物理链路之上实现。任何实现 DL 和 TL 的处理器或设备都可以开始共享内存。

+-----------+                         +-------------+
|           |                         |             |
|           |                         | Accelerated |
| Processor |                         |  Function   |
|           |  +--------+             |    Unit     |  +--------+
|           |--| Memory |             |    (AFU)    |--| Memory |
|           |  +--------+             |             |  +--------+
+-----------+                         +-------------+
     |                                       |
+-----------+                         +-------------+
|    TL     |                         |    TLX      |
+-----------+                         +-------------+
     |                                       |
+-----------+                         +-------------+
|    DL     |                         |    DLX      |
+-----------+                         +-------------+
     |                                       |
     |                   PHY                 |
     +---------------------------------------+

设备发现

OpenCAPI 依赖于设备上实现的类似 PCI 的配置空间。因此,主机可以通过查询配置空间来发现 AFU。

Linux 中的 OpenCAPI 设备被视为 PCI 设备(有一些注意事项)。固件应该抽象硬件,就好像它是一个 PCI 链接。许多现有的 PCI 基础设施被重用:在标准 PCI 枚举期间扫描设备并分配 BAR。因此可以使用 “lspci” 等命令来查看哪些设备可用。

配置空间定义了在物理适配器上可以找到的 AFU,例如其名称、它可以使用的内存上下文数量、其 MMIO 区域的大小等。

MMIO

OpenCAPI 为每个 AFU 定义了两个 MMIO 区域

  • 全局 MMIO 区域,其中包含与整个 AFU 相关的寄存器。

  • 每个进程的 MMIO 区域,每个上下文都有固定的大小。

AFU 中断

OpenCAPI 包括 AFU 向主机进程发送中断的可能性。它通过事务层中定义的 “intrp_req” 完成,指定一个 64 位对象句柄来定义中断。

驱动程序允许进程分配中断并获取其 64 位对象句柄,该句柄可以传递给 AFU。

字符设备

驱动程序为在物理设备上找到的每个 AFU 创建一个字符设备。一个物理设备可能有多个功能,每个功能可以有多个 AFU。但在撰写本文时,它只在使用仅导出一个 AFU 的设备进行过测试。

字符设备可以在 /dev/ocxl/ 中找到,并命名为:/dev/ocxl/<AFU 名称>.<位置>.<索引>

其中 <AFU 名称> 是一个最大 20 个字符长的名称,如 AFU 的配置空间中所见。<位置> 由驱动程序添加,可以在系统具有同一 OpenCAPI 设备的多个实例时帮助区分设备。<索引> 也有助于区分 AFU,以防设备携带同一 AFU 的多个副本。

Sysfs 类

为代表 AFU 的设备添加了一个 ocxl 类。请参见 /sys/class/ocxl。布局在 Documentation/ABI/testing/sysfs-class-ocxl 中描述

用户 API

打开

基于在配置空间中找到的 AFU 定义,一个 AFU 可能支持使用多个内存上下文,在这种情况下,关联的字符设备可能会被不同的进程多次打开。

ioctl

OCXL_IOCTL_ATTACH

将调用进程的内存上下文附加到 AFU,以便 AFU 可以访问其内存。

OCXL_IOCTL_IRQ_ALLOC

分配一个 AFU 中断并返回一个标识符。

OCXL_IOCTL_IRQ_FREE

释放先前分配的 AFU 中断。

OCXL_IOCTL_IRQ_SET_FD

将事件 fd 与 AFU 中断相关联,以便在 AFU 发送中断时可以通知用户进程。

OCXL_IOCTL_GET_METADATA

从卡中获取配置信息,例如 MMIO 区域的大小、AFU 版本和当前上下文的 PASID。

OCXL_IOCTL_ENABLE_P9_WAIT

允许 AFU 唤醒执行 “wait” 的用户空间线程。返回信息给用户空间,以允许它配置 AFU。请注意,这仅在 POWER9 上可用。

OCXL_IOCTL_GET_FEATURES

报告哪些影响 OpenCAPI 的 CPU 功能可从用户空间使用。

mmap

进程可以 mmap 每个进程的 MMIO 区域,以便与 AFU 进行交互。