与离路网络后端集成

https://blueprints.launchpad.net/nova/+spec/integration-with-off-path-network-backends

离路智能网卡 DPU 引入了一种架构变更,负责网卡交换机配置和代表接口插拔的网络代理运行在独立的 SoC 上,该 SoC 拥有自己的 CPU、内存和独立的操作系统内核。这种副作用是,超visor 主机名不再与 SmartNIC DPU 主机名匹配,而这些主机名会被 ovs-vswitchd 和 OVN [3] 代理看到,而现有的端口绑定代码依赖于此。本规范的目标是引入必要的变更,以扩展现有的硬件卸载代码,以应对主机名不匹配和相关的设计挑战,同时重用其余代码。为此,引入了带有唯一序列号的 PCIe 外接卡跟踪,以便可以用来确定负责特定 VF 的 SmartNIC DPU 的正确主机名。此外,建议在端口更新期间在“binding:profile”中传递更多信息,以方便代表端口的插拔。

问题描述

术语

  • 数据处理单元 (DPU) - 一种嵌入式系统,包括 CPU、网卡以及可能在其板载上的其他组件,通过一些 I/O 互连(例如 PCIe)与主板集成;

  • 离路智能网卡 DPU 架构 [1] [2] - 一种网卡核心负责编程网卡交换机的架构,当编程到网卡交换机的规则足以决定将数据包发送到哪里时,该架构会被绕过。通常,网卡核心仅参与“慢路径”的数据包转发,而“快路径”则由硬件(如 ASIC)处理;

  • 同路智能网卡 DPU 架构 [1] [2] - 一种网卡核心参与处理通过网卡的所有数据包的架构。换句话说,网卡核心始终处于所有数据包的“快路径”上;

  • 网卡交换机(或 eSwitch)- 存在于各种类型的网卡(支持 SR-IOV 的网卡、离路智能网卡)中的可编程嵌入式交换机。通常依赖于 ASIC 进行数据包处理;

  • switchdev [4] - 内核驱动程序模型,用于卸载内核的数据平面(转发平面)的交换设备。

  • 代表端口 [5] - switchdev 模型中引入的概念,用于模拟交换机端口的网络设备。这适用于网卡交换机端口(可以是物理上行端口、PF 或 VF);

  • devlink [6] - 内核 API,用于暴露与任何设备类不直接相关的设备信息和资源,例如芯片范围/交换机 ASIC 范围的配置;

  • PCI/PCIe 关键产品数据 (VPD) - 由 PCI(e) 端点暴露的标准功能,其中包含各种信息,包括卡的唯一序列号(只读、持久、工厂生成),该序列号由其暴露的所有功能共享。存在于 PCI 本地总线 2.1+ 和 PCIe 4.0+ 规范中。

详细概述

随着时间的推移,已经进行了跨项目的变更,以支持 SR-IOV VF 分配以及在支持 OVS 硬件卸载 [7] 的情况下支持 VF 分配,这些分配使用支持 switchdev 的网卡。

在使用“direct”类型的端口时,实例创建涉及几个关键步骤,包括

  • 基于客户端请求创建必要的上下文(包括 PCI 设备请求,例如基于与实例创建请求关联的“direct”端口或 flavor 的额外规格);

  • 选择将实例安排到哪个主机;

    • 在支持 switchdev 的网卡的情况下:基于 Nova DB 中记录的 PciDevices 的“switchdev”功能的设备的可用性;

  • 构建和运行实例,这涉及

    • 基于之前创建的 InstancePCIRequests 在目标主机上声明 PCI 资源;

    • 构建其他资源请求并更新 Neutron 端口信息,特别是

      • binding_host_id 与超visor 主机名;

      • binding:profile 详细信息与 PCI 设备信息,即:pci_vendor_info、pci_slot、physical_network;

  • 新创建实例的网络设备分配和 vif 插拔

    • 在支持 switchdev 的网卡的情况下,这涉及将 VF 代表端口插入到正确的 OVS 网桥中;

    • 将必要的流编程到网卡交换机中。

其余的描述将侧重于说明为什么需要改进此过程才能支持离路智能网卡 DPU。

离路智能网卡 DPU 为网卡交换机编程提供了一个专用的 CPU,在该 CPU 上设置了一个专用的操作系统以运行,该操作系统与主板上运行的操作系统分开。下图显示了一个带有 PCIe 分叉用于外接卡的智能网卡在一个多 CPU 系统中的示例

                       ┌──────────────────────────────┐
                       │  Main host (hypervisor)      │
                       │    ┌──────┐      ┌──────┐    │
                       │    │ CPU1 │      │ CPU2 │    │
                       │    │ RC1  │      │ RC2  │    │
                       │    └───┬──┘      └───┬──┘    │
                       │        │             │       │
                       └────────┼─────────────┼───────┘
                                │             │
                                │             │
                            ┌───┴────┐    ┌───┴────┐
          IO interconnect 1 │PF NUMA1│    │PF NUMA2│ IO interconnect 2
               (PCIe)       │VFs     │    │VFs     │    (PCIe)
                            └────┬───┘    └───┬────┘
                                 │            │
┌────────────────────────────────┼────────────┼──────────────────────┐
│SmartNIC DPU Board          ▲   │            │    ▲                 │
│                            │   │            │    │  Fast path      │
│      ┌─────────────┐         ┌─┴────────────┴─┐                    │
│      │ Application │e.g. PCIe│   NIC Switch   │     ┌────────────┐ │
│      │    CPU      ├─────────┤      ASIC      ├─────┤uplink ports│ │
│      │    RC3      │         ├────────────────┤     └────────────┘ │
│ ┌────┴──────┬──────┘   ◄──── │ Management CPU │                    │
│ │OOB Port   │       Slow path│    Firmware    │                    │
│ └───────────┘                └────────────────┘                    │
│                                                                    │
│                                                                    │
└────────────────────────────────────────────────────────────────────┘

使用离路智能网卡 DPU 时,如果网卡交换机具有必要的流编程,并且传入的数据包匹配这些流,则它会通过快路径传递到目的地,绕过“应用程序 CPU”。否则,数据包将在应用程序 CPU 上以软件方式处理,然后转发到目的地。

还有更复杂的场景

  • 每个服务器两个或多个智能网卡 DPU,连接到不同的 NUMA 节点;

  • 带有托管 PCIe 交换机的刀片系统,为不同的计算服务器提供相同外接卡的 PF/VF 的 SR-IOV 功能共享

    • MR-SR-IOV/PCIe 共享 IO [8]

预计网络代理(例如 ovs-vswitchd 和 ovn-controller)将在 SmartNIC OS 上运行,该 OS 将具有与超visor OS 不同的主机名,这导致端口绑定期间出现不匹配(更具体地说,对于 OVS 情况,Open_vSwitch 表中的 external_ids[“hostname”] 字段与超visor 主机名不同)。同样,代表插拔和流编程发生在 SmartNIC 主机上,而不是超visor 主机上。因此,Nova(在 os-vif 的帮助下)无法以相同的方式负责 VIF 插拔。例如,与 OVS 硬件卸载场景相比,OVS 网桥和端口代表不再暴露给超visor 主机 OS。总之,在此架构中,超visor 主机上不存在网络代理。在这种情况下,可以使用 noop os-vif 插件来避免 Nova 主机侧的显式操作,而不同的服务将在 SmartNIC DPU 侧负责将代表插入到正确的网桥中。但是,Nova 仍然负责将设备信息传递给 virt 驱动程序,以便在启动实例时可以使用它。

由于 Nova 和网络代理运行在不同的主机上,因此需要进行一组交互以

  • 将实例安排到存在具有必要功能的 VF 的主机;

  • 在超visor 主机侧选择合适的 VF 并为其创建 PCI 设备声明;

  • 运行 Neutron 规范中描述的必要逻辑 [19]

特别是由于以下原因,SmartNIC DPU 选择成为需要解决的问题

  • PF 和 VF mac 地址可以被重新编程,因此它们不能用作可靠的持久标识符来引用 SmartNIC DPU;

  • PCI(e) 外接卡本身在 sysfs 中没有条目,但 PCI(e) 端点有;

  • 当 SmartNIC DPU 使用 PCIe 访问网卡暴露的 PCIe 端点时,超visor 主机和 SmartNIC DPU 主机不会看到相同的 PCIe 功能集,因为它们看到的是**隔离的 PCIe 拓扑**。每个主机枚举它能够观察到的 PCIe 拓扑。虽然相同的网卡暴露给这两个拓扑,但主机观察到的功能和配置空间的集合不同。

    • 请注意,SmartNIC DPU 可能有不同的方式来访问支持 switchdev 的网卡:通过 PCIe、平台设备或其他 I/O 方式。超visor 主机无论如何都会看到 PCIe 端点,但依赖于 PCI 地址来实现功能及其代表是不切实际的。

为了跟踪 SmartNIC DPU 以及 PF/VF 与它们的关联,需要一个可从超visor 主机和 SmartNIC DPU 主机发现的唯一且持久的标识符。PCI (2.1+) 和 PCIe 规范定义了关键产品数据 (VPD) 功能,其中包括一个序列号字段,该字段被定义为给定外接卡的唯一且只读。由 PCI(e) 卡暴露的所有 PF 和 VF 共享相同 VPD 数据(无论是在 PF 上还是 VF 上暴露,取决于固件)。但是,此字段当前未被 virt 驱动程序收集或 Nova PciResourceTracker 记录(请注意:来自多家主要供应商的 SmartNIC DPU 已知提供带有填充序列号的 VPD,这些序列号可以从超visor 主机和 SmartNIC DPU 主机看到)。

通过 devlink-info 暴露的序列号信息也可通过 devlink 访问 - 它与特定的 IO 标准(如 PCI(e))没有关联,因此其他类型的设备(例如平台设备)也可以利用它。

对于 PCI(e) 用例,需要区分仅暴露 VPD 的 PF/VF 和也需要与 SmartNIC DPU 关联的 PF/VF。为了解决这个问题,可以使用 pci_passthrough_whitelist 标记 PCI 设备以表明它们与 SmartNIC DPU 关联。

依赖于“switchdev”功能(持久存储在 pci_devices 表的 extra_info 列中)也存在问题,因为由 SmartNIC DPU 板上的网卡暴露给超visor 主机的 PF 无法访问网卡交换机 - 不可能从超visor 侧查询网卡交换机是处于“legacy”模式还是“switchdev”模式。这与网卡内部以及相同网卡暴露给超visor 主机 CPU 和外接卡上的“应用程序 CPU”的方式有关。内核中的 Devlink 文档提供了一个示例,其中包含两个 PCIe 层次结构:[9]

用例

  • 主要用例是支持与离路智能网卡 DPU 关联的 VF 分配及其在 SmartNIC DPU 侧的必要配置;

  • 从操作员的角度来看,能够使用每个主机上的多个 SmartNIC DPU 是可取的。

期望的结果概述

以下几点总结了期望的结果

  • 离路 SmartNIC DPU 来自各种供应商,其中网络控制平面组件旨在在 SmartNIC DPU 主机上运行;

  • 重用现有的 VNIC 类型“smart-nic”(VNIC_SMARTNIC);

  • 用于指示设备与 SmartNIC DPU 关联的新 PCI 设备标签:remote_managed=True|False

  • 支持每个主机上的多个 SmartNIC DPU;

  • 不期望超visor 主机直接将镜像放置在 SmartNIC DPU 上;

    • 假定主板主机与 SmartNIC/DPU 之间存在安全边界;

    • Nova 与 SmartNIC DPU 上运行的软件之间的间接通信;

  • 最初关注 libvirt virt 驱动程序中的任何相关更改,但使设计通用,以便其他 virt 驱动程序可以遵循;

此规范的范围不包括 SmartNIC DPU 及其控制平面软件的配置和部署。

提议的变更

此更改的范围在 Nova 中,但它是涉及 OVN 和 Neutron 的更大工作的一部分。

总的来说,目标是收集通过 Nova 进行代表插拔所需的必要信息,并将其传递到正确的位置。

在 SmartNIC DPU 使用 PCIe 访问网卡时,属于同一物理机的超visor 主机和 SmartNIC DPU 主机可以看到由控制器暴露的 PCIe 功能,因此它们可以看到通过 VPD 暴露的相同的唯一外接卡序列号。对于其他类型的 I/O,可以依赖 devlink-info 来检索板序列号(如果可用)。但是,此更改侧重于 PCI 并将使用 Libvirt 看到的 PCI VPD 信息。

Nova 可以存储有关观察到的卡的信息,并在端口更新过程中使用它来影响用于代表插拔的 SmartNIC DPU 主机的选择。

pci_passthrough_whitelist 中的设备标签将告诉 Nova 哪些 PCI 供应商和设备 ID 指的是属于 SmartNIC DPU 的功能。

需要解决以下问题:

  • 存储来自每个 PciDevice 的 PCI(e) 功能的 VPD 信息;

    • card_serial_number - 一个最多 255 个字节的字符串,因为 PCI 和 PCIe 规范使用 1 字节长度字段来表示 SN;

    • extra_info: '{"capabilities": "vpd": {"card_serial_number": "<sn>"}]'};

  • 检索 Libvirt 暴露的节点设备 XML 格式中 PF 和 VF 呈现的 PCI VPD 中存储的 PCI 卡序列号。

    • PCI VPD 是否暴露给 VF 以及 PF 是特定于设备固件的(有时有一个 NVRAM 选项可以启用在 PF 之外的 VF 上暴露此数据) - 如果 PCI VPD 未暴露给 VF,则基于 PF 信息填充 VF 特定信息可能很有用;

  • 将序列号信息(如果存在)存储在 PciDevice extra_info 列的“vpd”功能下;

  • 扩展 pci_passthrough_whitelist 处理实现以考虑 remote_managed=True|False 标签;

  • 对于添加到实例的每个功能,收集超visor主机看到的PF MAC和VF逻辑编号,并在实例创建期间的端口更新请求期间(有关更多详细信息,请参阅下面的相关部分)将其传递给Neutron,以及卡的序列号;

    • 请注意,如果使用VFIO,此规范假定vfio-pci驱动程序仅绑定到VF,不绑定到PF,并且PF将用于超visor主机目的(例如,连接到控制平面的其余部分);

    • 可以将VF逻辑编号和PF MAC存储在extra_info中,以避免额外的数据库查找;

  • 添加逻辑以处理类型为VNIC_REMOTE_MANAGED(“远程管理”)的端口;

  • 添加一个新的Nova计算服务版本常量(SUPPORT_VNIC_TYPE_REMOTE_MANAGED)和实例构建时检查(在_validate_and_build_base_options中)以确保只有当所有单元中的所有计算服务都具有此服务版本时,才调度具有此端口类型的实例;

    • 服务版本检查只需要在包含具有VNIC_TYPE_REMOTE_MANAGED端口类型的port_ids的网络请求时触发。Nova需要学习通过其ID查询端口类型以执行该检查;

  • 添加一个新的计算驱动程序功能,称为supports_remote_managed_ports,以及相应的COMPUTE_REMOTE_MANAGED_PORTS trait到os-traits

    • 只有Libvirt驱动程序将被设置为具有此trait,因为它是第一个支持remote_managed端口的驱动程序;

  • 实现一个预过滤器,该过滤器将检查是否存在具有VNIC_TYPE_REMOTE_MANAGED端口类型的port ids,并且在这种情况下将COMPUTE_REMOTE_MANAGED_PORTS添加到请求规范中。这将确保实例被调度到具有支持远程管理端口的必要virt驱动程序启用的计算节点上;

  • 为具有VNIC_TYPE_REMOTE_MANAGED端口的实例,为以下操作添加计算服务版本检查

    • 创建服务器;

    • 附加VNIC_TYPE_REMOTE_MANAGED端口;

  • VNIC_TYPE_REMOTE_MANAGED添加到VNIC_TYPES_DIRECT_PASSTHROUGH列表中,因为Nova实例生命周期操作(如实时迁移)将以与那里已存在的其他VNIC类型相同的方式处理;

  • 避免为具有VNIC_TYPE_REMOTE_MANAGED端口的活动端口等待network-vif-plugged事件。

识别端口代表

此规范假定Neutron将被扩展以响应Nova传递的附加信息。建议在端口更新期间发送以下信息集

  • 卡序列号;

  • PF mac地址(超visor主机和SmartNIC DPU主机均可见);

  • VF逻辑编号。

这对于做出以下复用决策是必要的

  • 确定与所选VF关联的正确的SmartNIC DPU主机名。每个物理主机可能有多个SmartNIC DPU。可以通过在Neutron & OVN端将卡序列号与SmartNIC DPU主机名关联来完成(Nova只需要在端口更新中传递它);

  • 选择SmartNIC DPU侧正确的NIC Switch。PF逻辑编号与控制器相关联[9] [11]。通常,SmartNIC中只有一个NIC和NIC Switch,但不能保证不会有多个设备的设备。因此,仅传递超visor主机上的PF逻辑编号不足以确定正确的NIC Switch。可以使用PF MAC地址作为一种绕过超visor主机侧不可见控制器的解决方法;

  • 选择正确的VF代表 - 绑定到特定PF的VF逻辑编号。

SmartNIC DPU看到的PF和控制器编号对于超visor主机不可见,因为它看不到NIC Switch。为了进一步说明这一点,内核中的devlink [10]基础设施支持不同的端口风味(引述的描述来自linux/uapi/linux/devlink.h [12]

  • physical - “任何物理面向用户的端口”。超visor侧的PF和SmartNIC DPU上的上行端口将具有此风味;

  • virtual - “任何面向用户的虚拟端口”。超visor侧的VF将具有此风味;

  • pcipf - 表示PCI PF端口的NIC Switch端口;

  • pcivf - 表示PCI VF端口的NIC Switch端口。

Linux内核通过devlink以不同的方式为不同的端口风味暴露逻辑编号

  • physical和virtual风味:通过DEVLINK_ATTR_PORT_NUMBER - 此值是特定于驱动程序的,取决于设备驱动程序如何填充这些属性。

  • pcipf和pcivf风味:DEVLINK_ATTR_PORT_PCI_PF_NUMBER和DEVLINK_ATTR_PORT_PCI_VF_NUMBER属性。

例如,对于具有设置为两个上行端口的NIC,并且超visor侧的两个上行端口的sriov_numvfs都设置为4,则devlink port显示的接口集如下

pci/0000:05:00.0/1: type eth netdev enp5s0f0 flavour physical port 0
pci/0000:05:00.1/1: type eth netdev enp5s0f1 flavour physical port 1
pci/0000:05:02.3/1: type eth netdev enp5s0f1np0v0 flavour virtual port 0
pci/0000:05:02.4/1: type eth netdev enp5s0f1np0v1 flavour virtual port 0
pci/0000:05:02.5/1: type eth netdev enp5s0f1np0v2 flavour virtual port 0
pci/0000:05:02.6/1: type eth netdev enp5s0f1np0v3 flavour virtual port 0
pci/0000:05:00.3/1: type eth netdev enp5s0f0np0v0 flavour virtual port 0
pci/0000:05:00.4/1: type eth netdev enp5s0f0np0v1 flavour virtual port 0
pci/0000:05:00.5/1: type eth netdev enp5s0f0np0v2 flavour virtual port 0
pci/0000:05:00.6/1: type eth netdev enp5s0f0np0v3 flavour virtual port 0

请注意,虚拟端口索引都设置为0 - 在此示例中,设备驱动程序不通过devlink属性为“virtual”端口提供任何索引信息。

SmartNIC DPU主机devlink port输出

pci/0000:03:00.0/262143: type eth netdev p0 flavour physical port 0
pci/0000:03:00.0/196608: type eth netdev pf0hpf flavour pcipf pfnum 0
pci/0000:03:00.0/196609: type eth netdev pf0vf0 flavour pcivf pfnum 0 vfnum 0
pci/0000:03:00.0/196610: type eth netdev pf0vf1 flavour pcivf pfnum 0 vfnum 1
pci/0000:03:00.0/196611: type eth netdev pf0vf2 flavour pcivf pfnum 0 vfnum 2
pci/0000:03:00.0/196612: type eth netdev pf0vf3 flavour pcivf pfnum 0 vfnum 3
pci/0000:03:00.1/327679: type eth netdev p1 flavour physical port 1
pci/0000:03:00.1/262144: type eth netdev pf1hpf flavour pcipf pfnum 1
pci/0000:03:00.1/262145: type eth netdev pf1vf0 flavour pcivf pfnum 1 vfnum 0
pci/0000:03:00.1/262146: type eth netdev pf1vf1 flavour pcivf pfnum 1 vfnum 1
pci/0000:03:00.1/262147: type eth netdev pf1vf2 flavour pcivf pfnum 1 vfnum 2
pci/0000:03:00.1/262148: type eth netdev pf1vf3 flavour pcivf pfnum 1 vfnum 3

因此,代表风味的逻辑编号在SmartNIC DPU上正确识别,但在超visor主机上不可见。

超visor侧的VF PCI地址根据PCIe和SR-IOV规范使用PF PCI地址、“第一个VF偏移量”和“VF步长”值计算,并且逻辑per-PF编号由内核维护并通过sysfs暴露。因此,我们可以从以下sysfs条目中获取逻辑VF编号

/sys/bus/pci/devices/{pf_pci_addr}/virtfn<vf_logical_num>

它们也可以通过以下方式访问

/sys/bus/pci/devices/{vf_pci_addr}/physfn/virtfn<vf_logical_num>

通过解析virtfn symlinks逐个并将其结果与感兴趣的vf_pci_addr进行比较,可以找到正确的条目。

至于通过超visor主机PF的MAC地址找到正确的PF代表,取决于有关超visor PF MAC到PF代表MAC的映射的信息的可用性。

VF逻辑编号和PF MAC信息可以在端口更新之前运行时提取,因为这些信息由Nova Compute管理器在实例创建期间完成。或者,它可以存储在PciDevice的extra_info数据库中。

VF VLAN编程注意事项

除了NIC Switch功能未暴露给超visor主机之外,SmartNIC DPU也可能阻止VF的VLAN编程,因此,以下操作将失败(参见,[26]用于导致它的示例驱动程序代码,后来在[27]中修复)

sudo ip link set enp130s0f0 vf 2 vlan 0 mac de:ad:be:ef:ca:fe
RTNETLINK answers: Operation not permitted

在这种情况下,驱动程序允许VF MAC编程,但是不允许VLAN编程。

Nova不会告诉Libvirt为具有VIFHostDeviceDevType.ETHERNET[28]的VIF编程VLAN(它显式地将None传递给[29]的vlan参数),这些将被用于实现中。

Libvirt仅在提供设备XML时为hostdev端口编程VLAN编号[30]VIR_DOMAIN_NET_TYPE_HOSTDEV[31]),否则尝试通过将VLAN ID 0传递给RTM_SETLINK操作来清除VLAN([22]解决了此情况下的EPERM处理)。

Nova本身仅为VNIC_TYPE_MACVTAP端口编程MAC地址和VLAN[32] [33],因此,此规范的实现不需要引入任何更改。

备选方案

在寻找替代方案时,主要考虑的因素是

  • 代码重用:已经进行了大量的工作来实现硬件卸载,并且在不引入新的服务和项目的情况下扩展它将是首选;

  • 安全性和隔离:SmartNIC DPU有意与超visor主机隔离,以在超visor服务和网络服务之间创建安全边界。从超visor本身驱动配置和配置将消除这种优势;

  • NIC Switch配置和端口插拔:运行在SmartNIC DPU上的服务需要参与端口代表插拔和NIC Switch编程,这不一定特定于Nova甚至OpenStack。其他基础设施项目也可能受益于此,因此更大的工作需要集中在可重用性上。这就是为什么可能引入OpenStack特定的SmartNIC DPU级别服务需要避免(即,最好扩展OVN来执行此操作并在Nova侧处理VF插拔)。

一种替代方法涉及使用单独的服务跟踪卡,并使用其自己的API,并可能引入不同的VNIC类型:这没有代码重用的好处,并且需要添加另一个服务并将其与Nova和Neutron集成至少。似乎扩展为启用硬件卸载端口所做的工作是解决此用例的更有效方法。

最初支持每个主机一个SmartNIC DPU,并在以后扩展它已被放弃,因为数据模型扩展困难。

数据模型影响

PciDevices获得与它们关联的附加信息,而不会影响DB模型

  • 一个“vpd”功能,它存储PCI(e) VPD功能中可用的信息(最初,只是板序列号,但如果需要,以后可以扩展);

定期的超visor资源更新将添加新发现的PciDevices并获取关联的卡序列号信息。但是,旧设备不会在没有显式操作的情况下获得此信息。

REST API 影响

N/A

安全影响

N/A

通知影响

N/A

其他最终用户影响

N/A

性能影响

  • 需要执行其他步骤才能从PF和VF暴露的PCI(e)加卡中提取序列号信息。

其他部署者影响

自内核2.6.26以来,支持读取PCI(e)设备VPD(参见内核提交94e6108803469a37ee1e3c92dafdd1d59298602f),并且支持PCI本地总线2.1+(和任何PCIe修订版)的设备使用相同的二进制格式。根据PCI(e)规范,VPD功能是可选的,但是到目前为止观察到的生产SmartNIC/DPU包含它(工程样品可能没有VPD,因此仅使用通用硬件进行此操作)。

在部署计划期间,还需要考虑控制流量路径。预计Nova计算会将信息传递给Neutron以进行端口绑定,通过控制网络:Neutron然后负责与OVN交互,然后将必要的信息传播到运行在SmartNIC DPU主机上的ovn-控制器。此外,来自超visor节点的Placement服务更新通过控制网络发生。这可以通过在eSwitch上编程的专用端口来完成,这需要通过某种形式的部署自动化来完成。或者,许多主板上的LoM可用于该通信,但总体目标是消除对此的需求。如果存在,SmartNIC DPU上的OOB端口也可以用于控制通信,但假定它将用于PXE启动运行在应用程序CPU上的OS以及初始NIC Switch配置。哪些接口用于控制流量在本规范的范围之外,此注释的目的是说明在同一物理机器内的不同主机上运行的组件以及远程服务之间的可能的间接通信路径

                       ┌────────────────────────────────────┐
                       │  Hypervisor                        │    LoM Ports
                       │  ┌───────────┐       ┌───────────┐ │   (on-board,
                       │  │ Instance  │       │  Nova     │ ├──┐ optional)
                       │  │ (QEMU)    │       │ Compute   │ │  ├─────────┐
                       │  │           │       │           │ ├──┘         │
                       │  └───────────┘       └───────────┘ │            │
                       │                                    │            │
                       └────────────────┬─┬───────┬─┬──┬────┘            │
                                        │ │       │ │  │                 │
                                        │ │       │ │  │ Control Traffic │
                           Instance VF  │ │       │ │  │ PF associated   │
                                        │ │       │ │  │ with an uplink  │
                                        │ │       │ │  │ port or a VF.   │
                                        │ │       │ │  │ (used to replace│
                                        │ │       │ │  │  LoM)           │
   ┌────────────────────────────────────┼─┼───────┼─┼──┼─┐               │
   │   SmartNIC DPU Board               │ │       │ │  │ │               │
   │                                    │ │       │ │  │ │               │
   │  ┌──────────────┐ Control traffic  │ │       │ │  │ │               │
   │  │   App. CPU   │ via PFs or VFs  ┌┴─┴───────┴─┴┐ │ │               │
   │  ├──────────────┤  (DC Fabric)    │             │ │ │               │
   │  │ovn-controller├─────────────────┼─┐           │ │ │               │
   │  ├──────────────┤                 │ │           │ │ │               │
   │  │ovs-vswitchd  │     Port        │ │NIC Switch │ │ │               │
   │  ├──────────────┤   Representors  │ │  ASIC     │ │ │               │
   │  │    br-int    ├─────────────────┤ │           │ │ │               │
   │  │              ├─────────────────┤ │           │ │ │               │
   │  └──────────────┘                 │ │           │ │ │               │
   │                                   │ │           │ │ │               │
   │                                   └─┼───┬─┬─────┘ │ │               │
 ┌─┴──────┐Initial NIC Switch            │   │ │       │ │               │
─┤OOB Port│configuration is done via     │   │ │uplink │ │               │
 └─┬──────┘the OOB port to create        │   │ │       │ │               │
   │       ports for control traffic.    │   │ │       │ │               │
   └─────────────────────────────────────┼───┼─┼───────┼─┘               │
                                         │   │ │       │                 │
                                      ┌──┼───┴─┴───────┼────────┐        │
                                      │  │             │        │        │
                                      │  │   DC Fabric ├────────┼────────┘
                                      │  │             │        │
                                      └──┼─────────────┼────────┘
                                         │             │
                                         │         ┌───┴──────┐
                                         │         │          │
                                     ┌───▼──┐  ┌───▼───┐ ┌────▼────┐
                                     │OVN SB│  │Neutron│ │Placement│
                                     └──────┘  │Server │ │         │
                                               └───────┘ └─────────┘

超visor主机上的进程将使用与上行端口或绑定(或这些端口之上的VLAN接口)关联的PF,以便与控制进程通信。

SmartNIC DPU本身通常没有自己的BMC,并且从PCIe插槽获取主电源,因此其电源生命周期与主板生命周期相关联。在对超visor主机执行关机/开机操作时,应考虑到这一点,因为它会影响在SmartNIC DPU上运行的服务(超visor主机的重新启动不应影响)。

开发人员影响

当前规范的目标是libvirt驱动程序 - 其他virt驱动程序需要获得类似的功能才能发现卡序列号,如果他们想要支持相同的工作流程。

升级影响

Nova服务版本

Proposed Change》部分讨论了添加服务版本常量(SUPPORT_VNIC_TYPE_REMOTE_MANAGED)和跨所有单元的实例构建时检查。对于运营商而言,升级影响将是,在所有Nova计算服务升级以支持此服务版本之前,将无法使用此功能。

Neutron 集成

本节重点关注Neutron能够支持使用VNIC_TYPE_REMOTE_MANAGED端口类型启动的实例的运营问题。

在撰写本文时,只有 OVS 机制驱动程序支持 [13] VNIC_TYPE_REMOTE_MANAGED 端口,但前提是在 Neutron OpenvSwitch Agent 中设置了特定的配置选项(这是为了 Ironic 的目的而完成的,而不是 Nova [14])。

因此,在没有支持该类型端口的机制驱动程序,或者机制驱动程序未配置为处理该类型端口的情况下,端口绑定将失败。

此更改还依赖于使用 binding:profile [15],该属性没有严格的格式,并且记录如下:

A dictionary that enables the application running on the specific host to
pass and receive vif port information specific to the networking back-end.
The networking API does not define a specific format of this field.

因此,无需更改 Neutron API 来支持 Nova 在端口更新中传递的附加属性。

实现

负责人

主要负责人

dmitriis

其他贡献者

fnordahl, james-page

功能联络人

需要联络人

工作项

  • 支持 Libvirt 通过节点设备 XML 暴露的 PCI vpd 功能;

  • 实现修改以存储与 PciDevices 关联的卡序列号信息;

  • 修改 pci_passthrough_whitelist 以包含 remote_managed 标签处理;

  • 添加对 VNIC_SMARTNIC VNIC 类型的处理;

  • 实现基于 sysfs 中 virtfn 条目的 VF 逻辑编号提取:/sys/bus/pci/devices/{pf_pci_addr}/virtfn<vf_logical_num>

  • 扩展端口更新过程,以便将插件卡序列号、PF mac 和 VF 逻辑编号传递到 Neutron 的 binding:profile 属性中;

  • 实现添加功能的 Service 版本检查;

  • 实现一个预过滤器,以避免将实例调度到不支持正确计算能力的节点;

  • 单元测试覆盖率;

  • 添加功能的函数测试;

  • 与其他项目的集成测试。

依赖项

为了使整体功能更有用,需要额外的跨项目更改。具体来说,为了使其与 OVN 协同工作

  • ovn-controller 需要学习如何在 SmartNIC DPU 节点侧将 representors 插入到正确的桥接器中,因为将 VFs 连接起来的 os-vif 类似的功能仍然是必需的;

  • Neutron 中的 OVN 驱动程序代码需要了解 SmartNIC DPU 节点主机名以及通过 VPD 收集的各自的 PCIe 插件卡序列号

    • 端口绑定需要了解 hypervisor 和 SmartNIC DPU 主机名之间的不匹配以及卡序列号与 SmartNIC DPU 节点主机名之间的映射。相关的 Neutron RFE 处于 rfe-approved 状态 [18],相关的 Neutron 规范已发布在 [19],而其代码正在跟踪在 [20] 中进行;

  • Libvirt 支持解析 PCI/PCIe VPD,并且截至 2021 年 10 月 [21],如果 VPD 中存在序列号,则会暴露序列号;

  • Libvirt 尝试清除 VLAN(如果未指定 VLAN,则尝试将 VLAN ID 设置为 0),但是,某些 SmartNIC DPU 不允许 hypervisor 主机执行此操作,因为特权 NIC 交换机控制未提供给它。Libvirt 的补丁 [22] 解决了此问题。

未来工作

与硬件卸载 [7] 功能类似,此规范不涉及有关特定设备系列选择的运营问题。提出在放置服务中跟踪 PCI 设备的规范 [23] 可以朝着该方向迈进,但是,它可能需要 Neutron 扩展,这些扩展允许在与端口关联的元数据中指定请求的设备特征。

测试

  • 添加功能的单元测试;

  • 需要扩展函数测试以支持与添加的功能相关的其他情况;

文档影响

  • 需要扩展 Nova 管理员指南以讨论 remote_managed 标签;

  • 需要编写跨项目文档:需要更新 Neutron 和部署项目指南,以讨论如何部署具有 SmartNIC DPU 的云。

参考资料