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。如果在任何计算宿主机上没有可用的此类设备,则实例将无法调度。从这个意义上说,socket 与 require 相同,除了 PCI 设备必须属于同一个 socket,而不是同一个主机 NUMA 节点。在存在多个 NUMA 节点的情况下,PCI 设备必须属于与一个NUMA 节点相同的 socket。
为了更好地理解新的策略,请考虑一些示例。
在以下过于简化的图中,具有 hw_numa_nodes=1 和 hw_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() 实现将 required、preferred 和 legacy 识别为 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()所调用,以支持新的socketNUMA 亲和性策略。添加 COMPUTE_SOCKET_NUMA_AFFINITY trait(名称可以在实现期间调整)和相应的预过滤器。
扩展 flavor extra spec 验证以允许新的
socket值。
依赖项¶
无。
测试¶
虽然对 AMD Zen2 硬件在第三方 CI 中有期望,但距离太远,对本规范没有影响。功能测试就足够了。
文档影响¶
将记录新的 socket NUMA 亲和性策略的行为。可能需要记录使用新的 socket NUMA 亲和性策略对各种架构的性能影响的文档。
参考资料¶
历史¶
发布名称 |
描述 |
|---|---|
Wallaby |
引入 |