socket PCI NUMA 亲和性策略

https://blueprints.launchpad.net/nova/+spec/pci-socket-affinity

Nova 目前对 PCI 设备的 NUMA 亲和性的支持在可以表达的亲和性类型上受到限制。PCI 设备要么具有 NUMA 节点的亲和性,要么根本没有亲和性。这基于底层主机 NUMA 拓扑的两种假设之一。要么每个 socket 只有一个 NUMA 节点,要么 - 对于具有每个 socket 多个节点的芯片上集群拓扑 - 每个 NUMA 节点中的 CPU 足以容纳需要严格 PCI NUMA 亲和性的相当大的虚拟机。后者假设不再成立,Nova 需要一种更细致的方式来表达 PCI NUMA 亲和性。

问题描述

考虑一个具有 16 个 CPU 和一个 PCI 设备的客户机,以及一个 require PCI NUMA 亲和性策略。这样的策略要求客户机完全“适应”到 PCI 设备关联的主机 NUMA 节点。直到最近,这仍然是一个合理的期望:每个 NUMA 节点超过 16 个 CPU 是常态,即使在每个 socket 具有多个 NUMA 节点的宿主机上也是如此。

随着 AMD Zen2 架构等更新的硬件,情况不再如此。根据 BIOS 配置,每个 NUMA 节点可能只有 8 个 CPU。这有效地使得一个具有 require PCI 设备的 16 CPU 客户机无法被调度,因为没有主机 NUMA 节点可以容纳整个客户机。

参见

Zen2 BIOS 具有 L3AsNUMA 配置选项,它为每个 3 级缓存创建一个 NUMA 节点。最多 4 个核心可以共享一个 L3 缓存,每个核心有 2 个 SMT 线程。这就是数字 8 的由来。有关更多详细信息,请参阅 AMD 开发者文档 [1]

用例

作为 NFV 云运营商,我希望在不降低性能的情况下充分利用我的硬件(AMD Zen2 或启用芯片上集群的 Intel)。

提议的变更

本规范为 hw:pci_numa_affinity_policy(以及 hw_pci_numa_affinity_policy 镜像属性)提出一个新的值。该值为 socket,它表示实例的 PCI 设备必须与实例所固定到的主机 CPU 位于同一个 socket。如果在任何计算宿主机上没有可用的此类设备,则实例将无法调度。从这个意义上说,socketrequire 相同,除了 PCI 设备必须属于同一个 socket,而不是同一个主机 NUMA 节点。在存在多个 NUMA 节点的情况下,PCI 设备必须属于与一个NUMA 节点相同的 socket。

为了更好地理解新的策略,请考虑一些示例。

在以下过于简化的图中,具有 hw_numa_nodes=1hw_pci_numa_affinity_policy=socket 的实例可以固定到 NUMA 节点 N0 或 N1,但不能固定到 N2 或 N3

+----------+         +----------+
| N0    N1 |         | N2    N3 |
|          +---PCI   |          |
| Socket 0 |         | Socket 1 |
+----------+         +----------+

继续使用相同的图,如果实例具有 hw_numa_nodes=2,则它可以固定到以下节点,因为它们都至少有一个客户机 NUMA 节点固定到 PCI 设备的 socket。

  • N0 和 N1

  • N0 和 N2

  • N0 和 N3

  • N1 和 N2

  • N1 和 N3

实例不能固定到 N2 和 N3,因为它们都位于与 PCI 设备不同的 socket 上。

该实现需要知道主机 CPU 和 PCI 设备的 socket 亲和性。对于 CPU,libvirt 驱动程序从 libvirt 的主机功能中获取该信息,并将其保存在 NUMACell 对象中的一个新字段中。对于 PCI 设备,现有的 PCIDevice.numa_node 字段可用于查找相应的 NUMACell 对象并获取其 socket 亲和性。

然后,socket 亲和性信息在 hardware.py 的 numa_fit_instance_to_host() 中使用,特别是在它调用 PCI 管理器的 support_requests() 时。

备选方案

没有具有相似简单性的替代方案。更复杂的模型可以包括数字 NUMA 距离和/或 PCI 根复位器电气连接与内存映射亲和性。

在实现级别,一种替代方案是在每次查找 PCI 设备 socket 亲和性时将其保存在 PCIDevice 对象中的一个新字段中。这被排除在外,因为它会增加数据库迁移,并且灵活性和未来可扩展性较差。

另一种用于相同目的的替代方案是使用 PCIDevice 中的 extra_info 字段。它是一个可以接受任意新条目的 JSON blob。Nova 对象最初的目的之一是避免在网络上传输未版本化的字典。依赖于对象内的 JSON blob 与此相悖。此外,socket 亲和性适用于所有 PCI 设备,因此不属于特定设备的 extra_info 字典。

数据模型影响

  • NUMACell 对象中添加一个 socket 整数字段。由于该对象存储为 JSON blob,因此这里不需要进行数据库更改。该字段由 libvirt 驱动程序在运行时填充。

REST API 影响

没有 API 更改,当然也没有新的微版本。一个新的 socket 值被添加到 hw:pci_numa_affinity_policy flavor extra spec 和 hw_pci_numa_affinity_policy 镜像属性的可能值列表中。flavor extra spec 验证逻辑已扩展以支持新值。

安全影响

无。

通知影响

无。

其他最终用户影响

无。

性能影响

对 Nova 性能的影响很小。可能需要记录使用新的 socket NUMA 亲和性策略对各种架构的性能影响的文档。

其他部署者影响

无。

开发人员影响

只有 libvirt 驱动程序支持 PCI NUMA 亲和性策略。本规范基于该支持。

升级影响

当前(Wallaby 之前)的 _filter_pools_for_numa_cells() 实现将 requiredpreferredlegacy 识别为 hw_pci_numa_affinity_policy 的值,后者是通用的默认值。因此,具有 hw_pci_numa_affinity_policy=socket 的实例不能被允许降落在 Wallaby 之前的计算宿主机上:socket 值将不被识别,并且它们将被错误地视为具有 legacy 值。

为了确保只有 Wallaby 计算宿主机接收具有 hw_pci_numa_affinity_policy=socket 的实例,Wallaby libvirt 驱动程序报告一个新的 trait 来指示它支持新的策略。添加了相应的请求预过滤器。

实现

负责人

主要负责人

notartom

功能联络人

功能联络人

stephenfin

工作项

  • NUMACell 对象中添加一个 socket 整数字段。

  • Libvirt 驱动程序开始填充新的 NUMACell.socket 字段。

  • 修改 PciDeviceStats._filter_pools(),如 PciDeviceStats.support_requests() 所调用,以支持新的 socket NUMA 亲和性策略。

  • 添加 COMPUTE_SOCKET_NUMA_AFFINITY trait(名称可以在实现期间调整)和相应的预过滤器。

  • 扩展 flavor extra spec 验证以允许新的 socket 值。

依赖项

无。

测试

虽然对 AMD Zen2 硬件在第三方 CI 中有期望,但距离太远,对本规范没有影响。功能测试就足够了。

文档影响

将记录新的 socket NUMA 亲和性策略的行为。可能需要记录使用新的 socket NUMA 亲和性策略对各种架构的性能影响的文档。

参考资料

历史

修订

发布名称

描述

Wallaby

引入