Compute Engine 虚拟以太网 (gve) 的 Linux 内核驱动程序:¶
支持的硬件¶
GVE 驱动程序绑定到某些 Compute Engine VM 中发现的虚拟以太网设备使用的单个 PCI 设备 ID。
字段 |
值 |
注释 |
---|---|---|
供应商 ID |
0x1AE0 |
谷歌 |
设备 ID |
0x0042 |
|
子供应商 ID |
0x1AE0 |
谷歌 |
子设备 ID |
0x0058 |
|
修订 ID |
0x0 |
|
设备类别 |
0x200 |
以太网 |
PCI Bar¶
gVNIC PCI 设备公开了三个 32 位内存 BAR:- Bar0 - 设备配置和状态寄存器。- Bar1 - MSI-X 向量表 - Bar2 - IRQ、RX 和 TX 门铃
设备交互¶
- 驱动程序通过以下方式与设备交互
- 寄存器
MMIO 寄存器块
有关更多详细信息,请参见 gve_register.h
- 管理队列
参见下面的描述
- 重置
设备可以随时重置
- 中断
请参见下面支持的中断
- 发送和接收队列
参见下面的描述
描述符格式¶
GVE 支持两种描述符格式:GQI 和 DQO。这两种格式具有完全不同的描述符,将在下面进行描述。
寻址模式¶
GVE 支持两种寻址模式:QPL 和 RDA。QPL(“队列页列表”)模式通过一组预先注册的页面来传递数据。
对于 RDA(“原始 DMA 寻址”)模式,页面集是动态的。因此,数据包缓冲区可以位于访客内存中的任何位置。
寄存器¶
所有寄存器都是 MMIO。
这些寄存器用于初始化和配置设备,以及查询设备状态以响应管理中断。
字节序¶
管理队列消息和寄存器均为大端字节序。
GQI 描述符和数据路径寄存器均为大端字节序。
DQO 描述符和数据路径寄存器均为小端字节序。
管理队列 (AQ)¶
管理队列是一个 PAGE_SIZE 大小的内存块,被视为 AQ 命令数组,驱动程序使用它向设备发出命令并设置资源。驱动程序和设备会维护已提交和执行的命令计数。要发出 AQ 命令,驱动程序必须执行以下操作(具有适当的锁定)
将新命令复制到 AQ 数组中下一个可用的槽中
将其计数器增加新命令的数量
将计数器写入 GVE_ADMIN_QUEUE_DOORBELL 寄存器
轮询 ADMIN_QUEUE_EVENT_COUNTER 寄存器,直到其等于写入门铃的值,或直到超时。
设备将更新通过 ADMIN_QUEUE_EVENT_COUNTER 寄存器报告为已执行的每个 AQ 命令中的状态字段。
设备重置¶
通过将 0x0 写入 AQ PFN 寄存器来触发设备重置。这会导致设备释放驱动程序分配的所有资源,包括 AQ 本身。
中断¶
驱动程序支持以下中断
管理中断¶
设备使用管理中断来告知驱动程序查看 GVE_DEVICE_STATUS 寄存器。
管理 irq 的处理程序仅将服务任务排队到工作队列中,以检查寄存器并确认 irq。
通知块中断¶
通知块中断用于告知驱动程序轮询与该中断关联的队列。
这些 irq 的处理程序会调度该块的 napi 以运行并轮询队列。
GQI 流量队列¶
GQI 队列由一个描述符环和一个缓冲区组成,并分配给一个通知块。
描述符环是大小为 2 的幂的环形缓冲区,由固定大小的描述符组成。它们使用位于 Bar2 中的 __be32 门铃来移动其头指针。尾指针通过按顺序使用描述符并更新 __be32 计数器来移动。门铃和计数器都溢出到零。
每个队列的缓冲区必须事先在设备中注册为队列页列表,并且数据包数据只能放在这些页面中。
发送¶
gve 将发送环的缓冲区映射到 FIFO 中,并将数据包复制到 FIFO 中,然后再将其发送到网卡。
接收¶
接收环的缓冲区被放入一个与描述符环长度相同的数据环中,头指针和尾指针一起在环上移动。
DQO 流量队列¶
每个 TX 和 RX 队列都分配有一个通知块。
向设备发送描述符的 TX 和 RX 缓冲区队列使用 MMIO 门铃通知设备有新的描述符。
接收来自设备的描述符的 RX 和 TX 完成队列使用“生成位”来了解设备何时填充了描述符。驱动程序使用“当前生成”初始化所有位。设备将使用与当前生成相反的“下一个生成”填充收到的描述符。当环绕时,会交换当前/下一个生成。
驱动程序有责任确保 RX 和 TX 完成队列不会溢出。这可以通过限制发布到硬件的描述符数量来实现。
TX 数据包具有 16 位 completion_tag,RX 缓冲区具有 16 位 buffer_id。这些将在 TX 完成和 RX 队列上分别返回,以让驱动程序知道哪个数据包/缓冲区已完成。
发送¶
数据包的缓冲区被 DMA 映射以供设备在传输之前访问。成功发送数据包后,将取消映射缓冲区。
接收¶
驱动程序在 RX 缓冲区队列上将固定大小的缓冲区发布到硬件。在关联的 RX 队列上接收的数据包可能跨越多个描述符。