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 寄存器,直到它等于写入门铃的值,或直到超时。
设备将更新每个 AQ 命令中的状态字段,并通过 ADMIN_QUEUE_EVENT_COUNTER 寄存器报告为已执行。
设备重置¶
通过将 0x0 写入 AQ PFN 寄存器来触发设备重置。 这会导致设备释放驱动程序分配的所有资源,包括 AQ 本身。
中断¶
驱动程序支持以下中断
管理中断¶
设备使用管理中断来告诉驱动程序查看 GVE_DEVICE_STATUS 寄存器。
管理 irq 的处理程序只是将服务任务排队到工作队列中,以检查寄存器并确认 irq。
通知块中断¶
通知块中断用于告诉驱动程序轮询与该中断关联的队列。
这些 irq 的处理程序调度该块的 napi 运行并轮询队列。
GQI 流量队列¶
GQI 队列由描述符环和缓冲区组成,并分配给通知块。
描述符环是由固定大小描述符组成的二次幂大小的环形缓冲区。 它们使用位于 Bar2 中的 __be32 门铃来推进其头指针。 尾指针通过按顺序消耗描述符并更新 __be32 计数器来推进。 门铃和计数器都溢出为零。
每个队列的缓冲区必须提前在设备中注册为队列页面列表,并且数据包数据只能放入这些页面中。
发送¶
gve 将用于传输环的缓冲区映射到 FIFO 中,并在将数据包发送到 NIC 之前将数据包复制到 FIFO 中。
接收¶
用于接收环的缓冲区被放入数据环中,该数据环的长度与描述符环相同,并且头指针和尾指针一起在环上前进。
DQO 流量队列¶
每个 TX 和 RX 队列都分配有一个通知块。
TX 和 RX 缓冲区队列(将描述符发送到设备)使用 MMIO 门铃来通知设备有关新描述符。
RX 和 TX 完成队列(从设备接收描述符)使用“生成位”来了解设备何时填充了描述符。 驱动程序使用“当前生成”初始化所有位。 设备将使用与当前生成相反的“下一代”填充接收到的描述符。 当环回绕时,当前/下一代会交换。
驱动程序有责任确保 RX 和 TX 完成队列不会溢出。 这可以通过限制发布到 HW 的描述符数量来实现。
TX 数据包有一个 16 位 completion_tag,RX 缓冲区有一个 16 位 buffer_id。 这些将分别在 TX 完成队列和 RX 队列上返回,以让驱动程序知道哪个数据包/缓冲区已完成。
发送¶
在传输之前,数据包的缓冲区被 DMA 映射以供设备访问。 数据包成功传输后,缓冲区将被取消映射。
接收¶
驱动程序将固定大小的缓冲区发布到 RX 缓冲区队列上的 HW。 在关联的 RX 队列上接收到的数据包可能跨越多个描述符。