> For the complete documentation index, see [llms.txt](https://man.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://man.bsdcn.org/man4/iflib.4.md).

# iflib(4)

`iflib` — 网络接口驱动框架

## 名称

`iflib`

## 概要

`device pci device iflib`

## 描述

`iflib` 是一个面向 FreeBSD 的网络接口驱动框架。它旨在消除现代网络接口设备通常需要的大量样板代码，使驱动作者可以专注于其硬件所需的特定代码。这样可以共用一组 [sysctl(8)](/man8/sysctl.8.md) 名称，而非每个驱动单独命名。

## SYSCTL 变量

这些变量必须在加载驱动之前设置，可通过 loader.conf(5) 或通过 [kenv(1)](/man1/kenv.1.md) 进行。它们均以 `dev.X.Y.iflib.` 为前缀，其中 X 为驱动名称，Y 为实例编号。

**`override_nrxds`** 覆盖每个队列的 RX 描述符数量。该值为以逗号分隔的正整数列表。某些驱动仅使用单个值，但其他驱动可能使用多个值。这些数字必须是 2 的幂，零表示使用默认值。各个驱动可能对允许的值有额外限制。默认为全零。

**`override_ntxds`** 覆盖每个队列的 TX 描述符数量。该值为以逗号分隔的正整数列表。某些驱动仅使用单个值，但其他驱动可能使用多个值。这些数字必须是 2 的幂，零表示使用默认值。各个驱动可能对允许的值有额外限制。默认为全零。

**`override_qs_enable`** 设置后，允许发送和接收队列的数量不同。如未设置，将使用 TX 或 RX 队列数量中的较小值作为两者的数量。

**`override_nrxqs`** 设置 RX 队列的数量。如果为零，RX 队列数量由连接到控制器的套接字上的核心数推导得出。默认为 0。

**`override_ntxqs`** 设置 TX 队列的数量。如果为零，TX 队列数量由连接到控制器的套接字上的核心数推导得出。

**`disable_msix`** 禁用设备的 MSI-X 中断。

**`core_offset`** 指定分配队列的起始核心偏移量。如果值未指定或为 65535，则在各控制器之间按顺序分配核心。

**`separate_txrx`** 请求 RX 和 TX 队列不要配对在同一核心上。如果为零或未设置，则每个核心会分配一对 RX 和 TX 队列。设置为非零值时，TX 队列将分配到最后一个 RX 队列之后的核心上。

**`simple_tx`** 设置为 1 时，iflib 使用简单的发送例程，不进行任何排队。默认情况下，iflib 使用一种高度优化、无锁的发送队列，称为 mp\_ring。当 CPU 核心数多于 NIC 队列数时，此队列性能良好，并能防止发送资源的锁争用。不幸的是，在资源争用不成问题的工作负载下（在 NIC 队列数与 CPU 核心数相同的系统上运行良好的应用程序），mp\_ring 会带来不必要的开销。注意，启用此项时，tx\_abdicate sysctl 不再适用并被忽略。默认为零。

这些 [sysctl(8)](/man8/sysctl.8.md) 变量可随时更改：

**`tx_abdicate`** 控制发送环的服务方式。如果设为零，当一帧被提交到发送环时，提交它的同一任务将服务该环，除非已有任务正在服务 TX 环。这可确保每当有挂起的传输时，发送环都在被服务。这会导致更高的发送吞吐量。如果设为非零值，任务立即返回，发送环由不同的任务服务。这会更快地将控制权返回给调用者，并且在较高的接收负载下，可能会减少丢弃的 RX 帧。

**`tx_defer_mfree`** 控制 iflib 释放已发送数据包的内存（mbufs）的阈值（以包为单位）。当此值非零时，mbufs 将在发送锁之外释放。在使用 simple\_tx 时设置此项可减少锁争用和 CPU 使用。注意，此项仅在启用 simple\_tx 时适用。

**`tx_reclaim_thresh`** 控制 iflib 询问驱动可回收多少已发送数据包的阈值（以包为单位）。在某些驱动上，确定可回收多少数据包可能开销较大。

**`tx_reclaim_ticks`** 控制 iflib 询问驱动可回收多少已发送数据包的时间阈值（以滴答为单位）。在某些驱动上，确定可回收多少数据包可能开销较大。

**`rx_budget`** 设置一次接收的最大帧数。零（默认值）表示使用默认值（当前为 16）。

还有一些可更改所有驱动行为的全局 sysctl，可随时修改。

**`net.iflib.min_tx_latency`** 如果设置为非零值，iflib 将避免任何尝试合并多个发送，并尽快通知硬件有新描述符。这会降低最大吞吐量，但也会降低发送延迟。

**`net.iflib.no_tx_batch`** 某些 NIC 允许批量处理已完成的发送描述符。这样做通常通过减少发送中断的次数来提高发送吞吐量。将此项设置为非零值将禁用此功能。

这些 [sysctl(8)](/man8/sysctl.8.md) 变量为只读：

**`driver_version`** 表示驱动内部版本的字符串。

还有一些队列状态 [sysctl(8)](/man8/sysctl.8.md) 变量：

**`r_abdications`** 此队列的 MP 环中消费者让位次数。当 tx\_abdicate 为 true 时，每次环提交都会发生让位。

**`r_restarts`** 此队列的 MP 环中消费者重启次数。当尝试清空非空环失败且环已处于 STALLED 状态时，发生重启。

**`r_stalls`** 此队列的 MP 环中消费者停顿次数。当尝试清空非空环失败时，发生停顿。

**`r_starts`** 此队列的 MP 环中正常消费者启动次数。当 MP 环从 IDLE 转换为 BUSY 时，发生启动。

**`r_drops`** 此队列的 MP 环中丢弃次数。当尝试向没有可用空间的 MP 环添加条目时，发生丢弃。

**`r_enqueues`** 已入队到此队列 MP 环的条目数。

**`ring_state`** MP（软）环状态。这提供了当前 MP 环状态的快照，包括生产者头尾索引、消费者索引和状态。状态为 "IDLE"、"BUSY"、"STALLED" 或 "ABDICATED" 之一。

**`txq_cleaned`** 已回收的发送描述符数量。总已清理数。

**`txq_processed`** 已处理但可能尚未回收的发送描述符数量。

**`txq_in_use`** 已添加到发送队列但尚未清理的描述符。此值包括未发送的描述符以及已处理的描述符。

**`txq_cidx_processed`** 下一个要处理的描述符的发送队列消费者索引。

**`txq_cidx`** 要回收的最旧描述符的发送队列消费者索引。

**`txq_pidx`** 下一个要发送的描述符将插入到的发送队列生产者索引。

**`no_tx_dma_setup`** DMA 映射发送 mbuf 因 Er EFBIG 以外原因失败的次数。

**`txd_encap_efbig`** DMA 映射发送 mbuf 因所需段数过多而失败的次数。

**`tx_map_failed`** DMA 映射发送 mbuf 因任何原因失败的次数（no\_tx\_dma\_setup 和 txd\_encap\_efbig 之和）。

**`no_desc_avail`** 因发送环已满而无法向发送环添加描述符的次数。

**`mbuf_defrag_failed`** DMA 映射发送 mbuf 时返回 Er EFBIG 错误后，m\_collapse(9) 和 m\_defrag(9) 均失败的次数。

**`m_pullups`** 尝试解析头时调用 m\_pullup(9) 的次数。

**`mbuf_defrag`** 调用 m\_defrag(9) 的次数。

**`rxq_fl0.credits`** 接收环中当前可用的信用。

**`rxq_fl0.cidx`** 当前接收环消费者索引。

**`rxq_fl0.pidx`** 当前接收环生产者索引。

**`txqZ`** 以下内容为每个发送队列重复，其中 Z 为发送队列实例编号：

**`rxqZ`** 以下内容为每个接收队列重复，其中 Z 为接收队列实例编号：

当内核中启用 INVARIANTS 和/或 WITNESS 选项时，会暴露一些对驱动和 iflib 开发有用的附加 OID。

## 参见

[iflib(9)](/man9/iflib.9.md)

## 历史

此框架引入于 FreeBSD 11.0。
