启用 SR-IOV NIC 卸载功能发现

https://blueprints.launchpad.net/nova/+spec/enable-sriov-nic-features

如今,大多数网络硬件厂商都在 NIC 中实现了传统上由主机操作系统完成的 TCP/IP 协议栈的部分功能。将这些功能卸载到专用硬件可以释放 CPU 周期,供系统上运行的应用程序使用。

libvirt 在版本 1.2.14 中实现了 SR-IOV NIC 卸载功能发现 [1]。

问题描述

NIC 功能,特别是围绕各种硬件卸载的功能,对于网络密集型应用程序非常有用。不幸的是,Nova 尚未从系统检索物理 NIC 信息,这意味着调度器无法过滤掉包含特定 NIC 功能的计算主机。

此信息在调度过程中很有用,可以确定虚拟机应该位于哪个主机上。如果虚拟机在启动步骤期间请求特定的 NIC 卸载功能,Nova 调度器将过滤掉具有此功能的 PCI 设备的那些主机。

本规范的目的是通过提出一种读取此信息、存储它、在调度过程中使用它以及提供一种与 Neutron 共享此信息的方法来填补这一空白。

用例

  • NFV MANO/VNFM 系统需要确保将特定的网络 I/O 密集型工作负载启动到具有 SR-IOV NIC 硬件的计算主机上,该硬件具有一些特定的硬件卸载功能(例如 TSO 和校验和)。

提议的变更

本规范建议在 Nova 中实现以下更改

  • 一种读取 NIC 功能信息的方法。

  • 一种将此信息存储在 Nova DB 中的方法。

  • Nova 调度器 PCI 过滤器将如何匹配此新信息。

本规范还将描述如何定义 Neutron 端口以包含这些 NIC 功能。此信息将添加到 OpenStack 手册和 devref 中。

NIC 功能信息

libvirt API 当前提供 NIC 设备的特性列表。使用命令行实用程序,我们可以检索以下信息

$ virsh nodedev-dumpxml net_ens785_68_05_ca_34_83_60
<device>
  <name>net_ens785_68_05_ca_34_83_60</name>
  <path>/sys/devices/pci0000:00/0000:00:02.0/0000:02:00.0/net/ens785</path>
  <parent>pci_0000_02_00_0</parent>
  <capability type='net'>
    <interface>ens785</interface>
    <address>68:05:ca:34:83:60</address>
    <link state='down'/>
    <feature name='rx'/>   <-- example of NIC feature
    <feature name='tx'/>
    <feature name='sg'/>
    <feature name='tso'/>
    <feature name='gso'/>
    <feature name='gro'/>
    <feature name='rxvlan'/>
    <feature name='txvlan'/>
    <feature name='rxhash'/>
    <feature name='rdma'/>
    <feature name='txudptnl'/>
    <capability type='80203'/>
  </capability>
</device>

NIC 设备的父设备始终是一个唯一的 PCI 设备,并且此 PCI 设备的唯一子设备是 NIC 设备。本规范建议在 nova.virt.libvirt.config.LibvirtConfigNodeDevicePciCap 类中添加一个名为“net_features”的新成员。此成员将是一个字符串列表,例如“rx”、“tso”或“rxhash”。默认情况下,此列表为空。如果 PCI 设备不是 NIC 接口或没有任何特性,则该列表将保持为空。

存储 NIC 功能信息

数据库不需要任何更改。每个 PCI 设备的 NIC 信息将存储在 pci_devices.extra_info 下,在名为 capabilities 的字典中。此字典将包含所有发现的 PCI 功能,按类型分组。在这种情况下,因为这些特性与网络功能相关,所以它们将包含在一个名为 network 的列表中

extra_info: {'capabilities':
                {'network': ['gso', 'sg', 'tso', 'tx']}
            }

Neutron 端口 binding:profile

Neutron 数据模型和 API 已经定义。不需要对 Neutron 项目进行任何修改。

例如:如何定义具有 NIC 功能信息的 Neutron 端口

$ openstack port create --binding-profile
    '{"capabilities": ["rx", "tso"]}' --network private port1

Nova 调度器过滤器 PciPassthroughFilter

目前,虚拟机启动期间的 PCI 请求信息将同时来自 flavor 中提供的 PCI 别名信息和传递在启动命令中的 Neutron 端口定义。有了此功能,Neutron 端口将能够包含 NIC 功能列表。

为了将此新参数添加到过滤器中,PciDeviceStats PCI 设备池将包含一个新的标签键(“capabilities.network”)。因为池中的每个虚拟功能都属于同一个 PCI 设备,所以它们都具有相同的 NIC 功能。

如果 Neutron 端口的 PCI 请求规范具有 capabilities_network 参数,则过滤器将尝试将此值与存储在 PCI 设备池中的值进行匹配。

capabilities_network 参数在请求规范和 PCI 设备统计信息中都是列表。目前,PCI 直通过滤器仅匹配字符串参数 [2]。本规范建议更改此匹配函数以接受字符串和列表

  • 如果传递的是字符串,则函数将在两个字符串相等时通过。

  • 如果传递的是列表,则函数将在请求规范列表中的所有元素都包含在 PCI 设备池列表中时通过。

备选方案

  • 为了在 Neutron port 中创建一个新的成员,将特性信息作为字符串列表包含进去。但是,此更改不会增加任何价值,因为目前有一个地方,binding:profile,可以定义和存储此信息。

数据模型影响

无。

REST API 影响

无。

安全影响

无。

通知影响

其他最终用户影响

性能影响

Nova 调度器 PciPassthroughFilter 需要将“NIC 功能”参数包含在检查循环中,从而增加每个检查主机的额外时间。作为回报,由于新的限制,通过的主机列表可能会更短。

其他部署者影响

libvirt 在版本 1.2.14 中实现了 SR-IOV NIC 卸载功能发现 [1]。

开发人员影响

实现

负责人

主要负责人

Rodolfo Alonso <rodolfo.alonso.hernandez@intel.com> Sean K Mooney <sean.k.mooney@intel.com>

工作项

  1. 实现一种读取 NIC 功能信息的方法。

  2. 实现一种将此信息存储在 Nova DB 中的方法。

  3. 设计 Nova 调度器 PCI 过滤器将如何匹配此新信息。

  4. 添加文档说明如何在列出服务器时正确使用过滤器和排序参数。

  5. 为 NFV MANO 手册和 devref 添加足够的文档。

  6. 当资源提供者项目完全实施后,迁移此功能并将所有 NIC 功能添加到 os-traits 中。

依赖项

测试

需要调整一些单元测试才能正常工作。更改后,所有单元测试和功能测试都应通过。

一旦将具有特定硬件的第三方 CI 添加到 Jenkins,将添加新的测试。

文档影响

devref 需要描述

  • 将哪些新信息添加到 pci_devices 中以及从哪里获取。

  • 如何在 Nova Flavor extra specs 字段中定义新参数。

  • 如何使用这些新参数定义新的 Neutron 端口。

openstack-manuals SR-IOV 部分也必须包含此信息。

参考资料

[1] https://libvirt.org/news-2015.html [2] https://github.com/openstack/nova/blob/master/nova/pci/utils.py#L39-L54