DPDK Poll Mode Driver

372 篇文章 4 订阅
345 篇文章 27 订阅

轮询模式驱动

DPDK 包括 1 Gigabit、10 Gigabit 和 40 Gigabit 以及半虚拟化 virtio 轮询模式驱动程序。

轮询模式驱动程序 (PMD) 由 API 组成,通过在用户空间中运行的 BSD 驱动程序提供,用于配置设备及其各自的队列。此外,PMD 直接访问 RX 和 TX 描述符,无需任何中断(链路状态更改中断除外),以在用户应用程序中快速接收、处理和传送数据包。本节描述了 PMD 的要求、它们的全局设计原则,并提出了以太网 PMD 的高级架构和通用外部 API。

要求和假设

数据包处理应用程序的 DPDK 环境允许两种模型,run-to-completion和pipe-line:

  • 在 run-to-completion 模型中,特定端口的 RX 描述符环通过 API 轮询数据包。然后数据包在同一个core上处理,并通过 API 放置在端口的 TX 描述符环上进行传输。

  • 在pipe-line模型中,一个core通过 API 轮询一个或多个端口的 RX 描述符环。数据包被接收并通过环传递到另一个core。另一个core继续处理数据包,然后可以通过 API 将其放置在端口的 TX 描述符环上进行传输。

在同步run-to-completion模型中,分配给 DPDK 的每个逻辑core都会执行一个数据包处理循环,该循环包括以下步骤:

  • 通过 PMD 接收 API 获取输入数据包

  • 一次处理每个接收到的数据包,直至其转发

  • 通过 PMD 传输 API 发送挂起的输出数据包

相反,在异步pipe-line模型中,一些逻辑core可能专用于获取接收到的数据包,而其他逻辑core可能专用于处理先前接收到的数据包。接收到的数据包通过环在逻辑core之间进行交换。数据包获取循环包括以下步骤:

  • 通过 PMD 接收 API 获取输入数据包

  • 通过数据包队列将接收到的数据包提供给处理 lcores

数据包处理的循环包括以下步骤:

  • 从数据包队列中获取接收到的数据包

  • 处理接收到的数据包,如果转发则重新发送

为了避免任何不必要的中断处理开销,执行环境不得使用任何异步通知机制。在需要和适当的时候,应尽可能通过使用环来引入异步通信。

避免锁争用是多核环境中的关键问题。为了解决这个问题,PMD 被设计为尽可能多地使用每个核心的私有资源。例如,如果 PMD 不支持 RTE_ETH_TX_OFFLOAD_MT_LOCKFREE,则 PMD 会为每个内核、每个端口维护一个单独的传输队列。同样,端口的每个接收队列都分配给单个逻辑核心(lcore)并由其轮询。

为了遵守非统一内存访问 (NUMA),内存管理旨在为每个逻辑核心分配本地内存中的私有缓冲池,以最大限度地减少远程内存访问。数据包缓冲池的配置应考虑到底层物理内存架构的 DIMM、通道和等级。应用程序必须确保在创建内存池时提供适当的参数。请参阅内存池库。

设计原则 以太网* PMD 的 API 和架构在设计时考虑了以下准则。

PMD 必须帮助在上层应用程序级别强制执行面向全局策略的决策。相反,NIC PMD 功能不应阻碍上层全局策略预期的好处,或者更糟的是阻止此类策略的应用。

例如,PMD 的接收和发送功能都有最大数量的要轮询的数据包/描述符。这允许运行到完成处理堆栈静态修复或通过不同的全局循环策略动态调整其整体行为,例如:

  • 以零碎的方式一次一个地接收、处理和传输数据包。

  • 接收尽可能多的数据包,然后处理所有接收到的数据包,立即发送它们。

  • 接收给定的最大数量的数据包,处理接收到的数据包,累积它们,最后发送所有累积的数据包进行传输。

为了获得最佳性能,必须考虑整体软件设计选择和纯软件优化技术,并与可用的基于硬件的低级优化功能(CPU 缓存属性、总线速度、NIC PCI 带宽等)进行平衡。在优化面向突发的网络数据包处理引擎时,数据包传输的情况就是这种软件/硬件权衡问题的一个例子。在初始情况下,PMD 只能导出一个 rte_eth_tx_one 函数,以便在给定队列上一次传输一个数据包。最重要的是,可以轻松构建一个 rte_eth_tx_burst 函数,该函数循环调用 rte_eth_tx_one 函数来一次传输多个数据包。但是,PMD 有效地实现了一个 rte_eth_tx_burst 函数,以通过以下优化最小化每个数据包的驱动程序级传输成本:

  • 在多个数据包之间共享调用 rte_eth_tx_one 函数的未摊销成本。

  • 启用 rte_eth_tx_burst 函数以利用面向突发的硬件功能(在缓存中预取数据,使用 NIC 头/尾寄存器)来最小化每个数据包的 CPU 周期数,例如通过避免对环形传输描述符进行不必要的读取内存访问,或者通过系统地使用完全适合高速缓存行边界和大小的指针数组。

  • 应用面向突发的软件优化技术来消除原本无法避免的操作,例如环索引回绕管理。

还通过 API 为 PMD 密集使用的服务引入了面向突发的功能。这尤其适用于用于填充 NIC 环的缓冲区分配器,它提供一次分配/释放多个缓冲区的功能。例如,一个 mbuf_multiple_alloc 函数返回一个指向 rte_mbuf 缓冲区的指针数组,它在补充接收环的多个描述符时加速了 PMD 的接收轮询函数。

逻辑core、内存和 NIC 队列关系

当处理器的逻辑内核和接口使用其本地内存时,DPDK 支持 NUMA 以提供更好的性能。因此,与本地 PCIe* 接口相关的 mbuf 分配应该从本地内存中创建的内存池中分配。如果可能,缓冲区应保留在本地处理器上以获得最佳性能结果,并且 RX 和 TX 缓冲区描述符应填充从本地内存分配的内存池分配的 mbuf。

如果数据包或数据操作在本地内存中而不是在远程处理器内存中,则运行到完成模型的性能也会更好。如果使用的所有逻辑内核都位于同一处理器上,则流水线模型也是如此。

多个逻辑核心不应共享接口的接收或传输队列,因为这将需要全局锁定并影响性能。

如果 PMD 支持 RTE_ETH_TX_OFFLOAD_MT_LOCKFREE,则多个线程可以在同一个 tx 队列上同时调用 rte_eth_tx_burst() 而无需 SW 锁。此 PMD 功能可在某些 NIC 中找到,并且在以下用例中很有用:

  • 在 lcores 未映射到具有 1:1 关系的 Tx 队列的某些应用程序中删除显式自旋锁。

  • 在 eventdev 用例中,避免将单独的 TX 核心专用于传输,从而实现更多扩展,因为所有工作人员都可以发送数据包。

  • 有关 RTE_ETH_TX_OFFLOAD_MT_LOCKFREE 功能探测的详细信息,请参阅硬件卸载。

设备识别、所有权和配置

1.设备识别 每个 NIC 端口由其(总线/网桥、设备、功能)PCI 标识符唯一指定,该标识符由在 DPDK 初始化时执行的 PCI 探测/枚举功能分配。根据它们的 PCI 标识符,为 NIC 端口分配了另外两个标识符:

  • 一个端口索引,用于在 PMD API 导出的所有函数中指定 NIC 端口。

  • 用于在控制台消息中指定端口的端口名称,用于管理或调试目的。为方便使用,端口名称中包含端口索引。

2.端口所有权 以太网设备端口可由单个 DPDK 实体(应用程序、库、PMD、进程等)拥有。所有权机制由 ethdev API 控制,并允许 DPDK 实体设置/删除/获取端口所有者。它防止以太网端口被不同的实体管理。

建议尽早设置端口所有权,例如在探测通知 RTE_ETH_EVENT_NEW 期间。

3.设备配置 每个网卡端口的配置包括以下操作:

  • 分配 PCI 资源

  • 将硬件(发出全局重置)重置为众所周知的默认状态

  • 设置 PHY 和链路

  • 初始化统计计数器

PMD API 还必须导出函数来启动/停止端口的全组播功能,以及在混杂模式下设置/取消设置端口的函数。

某些硬件卸载功能必须在端口初始化时通过特定配置参数单独配置。例如,接收端缩放 (RSS) 和数据中心桥接 (DCB) 功能就是这种情况。

4.On-the-Fly配置 可以“动态”启动或停止的所有设备功能(即,无需停止设备)不需要 PMD API 导出为此目的的专用功能。

所需要的只是设备 PCI 寄存器的映射地址,以在驱动程序之外的特定功能中实现这些功能的配置。

为此,PMD API 导出一个函数,该函数提供与设备相关的所有信息,这些信息可用于在驱动程序之外设置给定的设备功能。这包括 PCI 供应商标识符、PCI 设备标识符、PCI 设备寄存器的映射地址以及驱动程序的名称。

这种方法的主要优点是它可以完全自由地选择用于配置、启动和停止此类功能的 API。

例如,请参阅 testpmd 应用程序中英特尔® 82576 千兆以太网控制器和英特尔® 82599 10 千兆以太网控制器控制器的 IEEE1588 功能配置。

其他特性,例如端口的 L3/L4 5-Tuple 包过滤特性,可以用同样的方式进行配置。以太网* 流量控制(暂停帧)可以在单个端口上配置。有关详细信息,请参阅 testpmd 源代码。此外,只要正确设置了数据包 mbuf,就可以为单个数据包启用 NIC 的 L4 (UDP/TCP/SCTP) 校验和卸载。有关详细信息,请参阅硬件卸载。

(免费订阅,永久学习)学习地址: Dpdk/网络协议栈/vpp/OvS/DDos/NFV/虚拟化/高性能专家-学习视频教程-腾讯课堂

更多DPDK相关学习资料有需要的可以自行报名学习,免费订阅,永久学习,或点击这里加qun免费
领取,关注我持续更新哦! ! 

5.传输队列的配置 每个传输队列都独立配置有以下信息:

  • 发送环的描述符数

  • 用于标识适当的 DMA 内存区域的套接字标识符,在 NUMA 架构中从该内存区域分配发送环

  • 发送队列的 Prefetch、Host 和 Write-Back 阈值寄存器的值

  • 最小传输数据包到空闲阈值 (tx_free_thresh)。当用于传输数据包的描述符数量超过此阈值时,应检查网络适配器以查看它是否已写回描述符。在 TX 队列配置期间可以传递 0 值,以指示应使用默认值。 tx_free_thresh 的默认值为 32。这确保 PMD 不会搜索已完成的描述符,直到 NIC 为该队列处理了至少 32 个描述符。

  • 最小 RS 比特阈值。在发送描述符中设置报告状态 (RS) 位之前要使用的最小发送描述符数。请注意,此参数可能仅对 Intel 10 GbE 网络适配器有效。如果自上一个 RS 位设置以来使用的描述符数量(直到用于传输数据包的第一个描述符)超过传输 RS 位阈值 (tx_rs_thresh),则在用于传输数据包的最后一个描述符上设置 RS 位。简而言之,此参数控制网络适配器将哪些传输描述符写回主机内存。在 TX 队列配置期间可以传递 0 值,以指示应使用默认值。 tx_rs_thresh 的默认值为 32。这确保在网络适配器写回最近使用的描述符之前至少使用了 32 个描述符。这节省了由 TX 描述符回写产生的上游 PCIe* 带宽。请务必注意,当 tx_rs_thresh 大于 1 时,应将 TX 回写阈值 (TX wthresh) 设置为 0。有关更多详细信息,请参阅英特尔® 82599 10 Gigabit 以太网控制器数据表。

tx_free_thresh 和 tx_rs_thresh 必须满足以下约束:

  • tx_rs_thresh 必须大于 0。

  • tx_rs_thresh 必须小于环的大小减 2。

  • tx_rs_thresh 必须小于或等于 tx_free_thresh。

  • tx_free_thresh 必须大于 0。

  • tx_free_thresh 必须小于环的大小减 3。

  • 为获得最佳性能,当 tx_rs_thresh 大于 1 时,应将 TX wthresh 设置为 0。

TX 环中的一个描述符用作标记以避免硬件竞争条件,因此有最大阈值约束。

6.Free Tx mbuf on Demand 许多驱动程序不会在数据包传输后立即将 mbuf 释放回内存池或本地缓存。相反,它们将 mbuf 留在其 Tx 环中,并在超过 tx_rs_thresh 时执行批量释放,或者在需要 Tx 环中的插槽时释放 mbuf。

应用程序可以通过 rte_eth_tx_done_cleanup() API 请求驱动程序释放使用过的 mbuf。此 API 请求驱动程序释放不再使用的 mbuf,与是否已超过 tx_rs_thresh 无关。应用程序可能希望立即释放 mbuf 有两种情况:

  • 当需要将给定数据包发送到多个目标接口时(用于第 2 层泛洪或第 3 层多播)。一种选择是制作数据包的副本或需要操作的标头部分的副本。第二种选择是传输数据包,然后轮询 rte_eth_tx_done_cleanup() API,直到数据包上的引用计数减少。然后可以将相同的数据包传输到下一个目标接口。应用程序仍负责管理不同目标接口之间所需的任何数据包操作,但可以避免数据包复制。此 API 与数据包是否被传输或丢弃无关,只是接口不再使用 mbuf。

  • 某些应用程序旨在进行多次运行,例如数据包生成器。出于性能原因和运行之间的一致性,应用程序可能希望在每次运行之间重置回初始状态,其中所有 mbuf 都返回到内存池。在这种情况下,它可以为它一直使用的每个目标接口调用 rte_eth_tx_done_cleanup() API,以请求它释放所有已使用的 mbuf。

要确定驱动程序是否支持此 API,请检查网络接口控制器驱动程序文档中的 Free Tx mbuf on demand 功能。

7. 硬件卸载 根据 rte_eth_dev_info_get() 公布的驱动程序功能,PMD 可能支持硬件卸载功能,如校验和、TCP 分段、VLAN 插入或同一 TX 队列上的无锁多线程 TX 突发。

对这些卸载功能的支持意味着将专用状态位和值字段添加到 rte_mbuf 数据结构中,以及由每个 PMD 导出的接收/发送功能对其进行适当处理。标志列表及其确切含义在 mbuf API 文档和 Mbuf 库中的“元信息”部分中进行了描述。

7.1每端口和每队列卸载 在 DPDK 卸载 API 中,卸载分为 per-port 和 per-queue offload,如下所示:

  • 可以在一个队列上启用按队列卸载,同时在另一个队列上禁用。

  • 纯粹的每端口卸载是设备支持但不支持每队列类型的卸载。

  • 不能在一个队列上启用纯粹的每端口卸载,同时在另一个队列上禁用它。

  • 必须同时在所有队列上启用或禁用纯每端口卸载。

  • 任何卸载都是按队列或纯按端口类型,但不能在同一设备上同时采用两种类型。

  • 端口能力 = 每个队列的能力 + 纯粹的每个端口的能力。

  • 可以在所有队列上启用任何支持的卸载。

可以使用 rte_eth_dev_info_get() 查询不同的卸载功能。从 rte_eth_dev_info_get() 返回的 dev_info->[rt]x_queue_offload_capa 包括所有每个队列的卸载功能。从 rte_eth_dev_info_get() 返回的 dev_info->[rt]x_offload_capa 包括所有纯每个端口和每个队列的卸载功能。支持的卸载可以是每个端口或每个队列。

使用现有的 RTE_ETH_TX_OFFLOAD* 或 RTE_ETH_RX_OFFLOAD* 标志启用卸载。应用程序请求的任何卸载都必须在设备能力范围内。如果未在参数 dev_conf->[rt]xmode.offloads 到 rte_eth_dev_configure() 和 [rt]x_conf->offloads 到 rte_eth_[rt]x_queue_setup() 中设置任何卸载,则默认情况下禁用任何卸载。

如果应用程序在 rte_eth_dev_configure() 中启用了任何卸载,则无论是按队列还是按端口类型,无论是在 [rt]x_conf->offloads 中设置还是清除它,它都会在所有队列上启用rte_eth_[rt]x_queue_setup()。

如果在 rte_eth_dev_configure() 中没有启用按队列卸载,则可以在 rte_eth[rt]x_queue_setup() 中为单个队列启用或禁用它。应用程序输入的 [rt]x_conf->offloads 到 rte_eth[rt]x_queue_setup() 中新添加的卸载是尚未在 rte_eth_dev_configure() 中启用并请求在 rte_eth_[rt]x_queue_setup() 中启用的卸载.它必须是 per-queue 类型,否则会触发错误日志。

Poll Mode Driver API

1. 通用性 默认情况下,PMD 导出的所有函数都是无锁函数,假定不会在不同的逻辑内核上并行调用这些函数来处理同一个目标对象。例如,不能在两个逻辑内核上并行调用 PMD 接收函数来轮询同一端口的同一 RX 队列。当然,这个函数可以被不同的逻辑核在不同的RX队列上并行调用。执行此规则是上层应用程序的责任。

如果需要,多个逻辑核对共享队列的并行访问可以通过在 PMD API 的相应无锁函数之上构建的专用内联锁感知函数显式保护。

2. 通用数据包表示 一个数据包由一个 rte_mbuf 结构表示,它是一个包含所有必要内务信息的通用元数据结构。这包括与卸载硬件功能相对应的字段和状态位,例如 IP 标头或 VLAN 标签的校验和计算。

rte_mbuf 数据结构包括特定字段,以通用方式表示网络控制器提供的卸载功能。对于输入数据包,rte_mbuf 结构的大部分字段由 PMD 接收函数填充,其中包含接收描述符中包含的信息。相反,对于输出数据包,rte_mbuf 结构的大部分字段都被 PMD 发送函数用于初始化发送描述符。

mbuf 结构在 Mbuf 库章节中有完整的描述。

3.以太网设备API 以太网 PMD 导出的以太网设备 API 在 DPDK API 参考中进行了描述。

4. 以太网设备标准设备参数 标准以太网设备参数允许一组适用于所有以太网设备的常用参数/参数可用于指定特定设备并将通用配置参数传递到这些端口。

支持创建表示器端口的设备的表示器 此参数允许用户指定启用端口表示器的交换机端口。一个设备参数中的多个表示器无效:

-a DBDF,representor=vf0
-a DBDF,representor=vf[0,4,6,9]
-a DBDF,representor=vf[0-31]
-a DBDF,representor=vf[0,2-4,7,9-11]
-a DBDF,representor=sf0
-a DBDF,representor=sf[1,3,5]
-a DBDF,representor=sf[0-1023]
-a DBDF,representor=sf[0,2-4,7,9-11]
-a DBDF,representor=pf1vf0
-a DBDF,representor=pf[0-1]sf[0-127]
-a DBDF,representor=pf1

注意:PMD 不需要支持标准设备参数,用户应查阅相关 PMD 文档以查看支持 devargs

5.扩展统计API 扩展统计 API 允许 PMD 公开所有可用的统计信息,包括设备独有的统计信息。每个统计信息都有三个属性名称、id 和值:

  • name:由下面详述的方案格式化的人类可读字符串。

  • id:仅表示该统计信息的整数。

  • value:一个无符号的 64 位整数,它是统计数据的值。

请注意,扩展的统计标识符是特定于驱动程序的,因此对于不同的端口可能不同。 API 由各种 rte_eth_xstats_*() 函数组成,并允许应用程序灵活地检索统计信息。

5.1 人类可读名称方案 公开给 API 客户端的字符串存在命名方案。这是为了允许抓取 API 以获取感兴趣的统计信息。命名方案使用由单个下划线 _ 分隔的字符串。方案如下:

  • direction

  • detail 1

  • detail 2

  • detail n

  • unit

常见统计 xstats 字符串的示例,其格式符合上述方案:

  • rx_bytes

  • rx_crc_errors

  • tx_multicast_packets

该方案虽然非常简单,但可以灵活地从统计字符串中呈现和读取信息。以下示例说明了命名方案:rx_packets。在此示例中,字符串被分成两个部分。第一个组件 rx 表示该统计信息与 NIC 的接收端相关联。第二个组成部分packets表示计量单位是packets。

一个更复杂的例子:tx_size_128_to_255_packets。在这个例子中,tx 表示传输,size 是第一个细节,128 等是更多细节,packets 表示这是一个数据包计数器。

元数据方案中的一些补充如下:

  • 如果第一部分与 rx 或 tx 不匹配,则统计信息与接收或发送都没有关联。

  • 如果第二部分的第一个字母是 q,并且这个 q 后跟一个数字,那么这个统计数据是特定队列的一部分。

使用队列号的示例如下: tx_q7_bytes 表示此统计信息适用于队列号 7,并表示该队列上传输的字节数。

5.2. API 设计 xstats API 使用名称、id 和值来允许对特定统计信息进行高效查找。高性能查找意味着两件事;

  • 没有字符串与快速路径中的统计信息名称进行比较

  • 只允许请求感兴趣的统计信息

API 通过将统计信息的名称映射到唯一的 ID 来确保满足这些要求,该 ID 用作在快速路径中查找的键。 API 允许应用程序请求一组 id 值,以便 PMD 只执行所需的计算。预期用途是应用程序扫描每个统计信息的名称,如果它对该统计信息感兴趣,则缓存 id。在快速路径上,整数可用于检索 id 表示的统计数据的实际值。

5.3. API 函数 API 由少量函数构建而成,可用于检索统计数据的数量以及这些统计数据的名称、ID 和值。

  • rte_eth_xstats_get_names_by_id():返回统计信息的名称。当给定一个 NULL 参数时,该函数返回可用的统计信息的数量。

  • rte_eth_xstats_get_id_by_name():搜索与 xstat_name 匹配的统计 ID。如果找到,则设置 id 整数。

  • rte_eth_xstats_get_by_id():用匹配提供的 ids 数组填充 uint64_t 值数组。如果 ids 数组为 NULL,则返回所有可用的统计信息。

5.4.应用程序使用 想象一个想要查看丢弃数据包计数的应用程序。如果没有丢弃任何数据包,则应用程序不会出于性能原因读取任何其他指标。如果数据包被丢弃,则应用程序会请求一组特定的统计信息。这组统计数据允许应用程序决定接下来要执行的步骤。以下代码片段显示了如何使用 xstats API 来实现此目标。

第一步是获取所有统计信息名称并列出它们:

uint64_t *values;
int len, i;
​
/* Get number of stats */
len = rte_eth_xstats_get_names_by_id(port_id, NULL, NULL, 0);
if (len < 0) {
    printf("Cannot get xstats count\n");
    goto err;
}
​
xstats_names = malloc(sizeof(struct rte_eth_xstat_name) * len);
if (xstats_names == NULL) {
    printf("Cannot allocate memory for xstat names\n");
    goto err;
}
​
/* Retrieve xstats names, passing NULL for IDs to return all statistics */
if (len != rte_eth_xstats_get_names_by_id(port_id, xstats_names, NULL, len)) {
    printf("Cannot get xstat names\n");
    goto err;
}
​
values = malloc(sizeof(values) * len);
if (values == NULL) {
    printf("Cannot allocate memory for xstats\n");
    goto err;
}
​
/* Getting xstats values */
if (len != rte_eth_xstats_get_by_id(port_id, NULL, values, len)) {
    printf("Cannot get xstat values\n");
    goto err;
}
​
/* Print all xstats names and values */
for (i = 0; i < len; i++) {
    printf("%s: %"PRIu64"\n", xstats_names[i].name, values[i]);
}

应用程序可以访问 PMD 公开的所有统计信息的名称。应用程序可以决定哪些统计信息是感兴趣的,通过查找名称来缓存这些统计信息的 id,如下所示:

uint64_t id;
uint64_t value;
const char *xstat_name = "rx_errors";
​
if(!rte_eth_xstats_get_id_by_name(port_id, xstat_name, &id)) {
    rte_eth_xstats_get_by_id(port_id, &id, &value, 1);
    printf("%s: %"PRIu64"\n", xstat_name, value);
}
else {
    printf("Cannot find xstats with a given name\n");
    goto err;
}

API 为应用程序提供了灵活性,因此它可以使用包含多个 ID 号的数组来查找多个统计信息。这减少了检索统计信息的函数调用开销,并使应用程序查找多个统计信息更简单。

#define APP_NUM_STATS 4
/* application cached these ids previously; see above */
uint64_t ids_array[APP_NUM_STATS] = {3,4,7,21};
uint64_t value_array[APP_NUM_STATS];
​
/* Getting multiple xstats values from array of IDs */
rte_eth_xstats_get_by_id(port_id, ids_array, value_array, APP_NUM_STATS);
​
uint32_t i;
for(i = 0; i < APP_NUM_STATS; i++) {
    printf("%d: %"PRIu64"\n", ids_array[i], value_array[i]);
}

这个用于 xstats 的数组查找 API 允许应用程序创建多个统计“组”,并使用单个 API 调用查找这些 ID 的值。作为最终结果,应用程序能够实现其监控单个统计信息(在本例中为“rx_errors”)的目标,如果这表明数据包被丢弃,它可以使用 IDs 数组参数轻松检索“一组”统计信息到 rte_eth_xstats_get_by_id 函数。

NIC Reset API

int rte_eth_dev_reset(uint16_t port_id);

有时必须被动重置端口。例如,当一个 PF 被重置时,它的所有 VF 也应该由应用程序重置,以使它们与 PF 一致。 DPDK 应用程序也可以调用此函数来触发端口复位。通常,当检测到 RTE_ETH_EVENT_INTR_RESET 事件时,DPDK 应用程序会调用此函数。

PMD 的职责是触发 RTE_ETH_EVENT_INTR_RESET 事件,并且应用程序应该注册一个回调函数来处理这些事件。当 PMD 需要触发复位时,它可以触发 RTE_ETH_EVENT_INTR_RESET 事件。收到 RTE_ETH_EVENT_INTR_RESET 事件后,应用程序可以按如下方式处理它:停止工作队列,停止调用 Rx 和 Tx 函数,然后调用 rte_eth_dev_reset()。为了线程安全,所有这些操作都应该从同一个线程中调用。

例如,当 PF 被复位时,PF 会发送消息通知 VFs 该事件并触发对 VFs 的中断。然后在中断服务程序中,VFs 检测到这个通知消息并调用 rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET, NULL)。这意味着 PF 复位会触发 VF 中的 RTE_ETH_EVENT_INTR_RESET 事件。函数 rte_eth_dev_callback_process() 将调用注册的回调函数。回调函数可以触发应用程序处理 VF 重置所需的所有操作,包括停止 Rx/Tx 队列和调用 rte_eth_dev_reset()。

rte_eth_dev_reset() 本身是一个通用函数,它只通过调用 dev_unint() 和 dev_init() 进行一些硬件复位操作,本身不处理同步,由应用程序处理。

PMD 本身不应调用 rte_eth_dev_reset()。 PMD 可以触发应用程序处理复位事件。应用程序有责任在调用 rte_eth_dev_reset() 之前处理所有同步。

翻译自:12. Poll Mode Driver

原文链接: https://zhuanlan.zhihu.com/p/558274437

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值