多队列网络设备支持指南¶
第 1 节:实现多队列支持的基本驱动程序要求¶
简介:内核对多队列设备的支持¶
内核始终支持多队列设备。
基本驱动程序需要使用新的 alloc_etherdev_mq() 或 alloc_netdev_mq() 函数来为设备分配子队列。底层内核 API 将负责子队列内存的分配和释放,以及队列在内存中的 netdev 配置。
基本驱动程序还需要像现在管理全局 netdev->queue_lock 一样管理队列。因此,基本驱动程序应使用 netif_{start|stop|wake}_subqueue() 函数来管理每个队列,同时设备仍在运行。当设备上线或完全关闭时(unregister_netdev()
等),仍然使用 netdev->queue_lock。
第 2 节:多队列设备的 Qdisc 支持¶
目前,有两个 qdisc 针对多队列设备进行了优化。第一个是默认的 pfifo_fast qdisc。此 qdisc 支持每个硬件队列一个 qdisc。一个新的循环调度 qdisc,sch_multiq 也支持多个硬件队列。qdisc 负责对 skb 进行分类,然后根据 skb->queue_mapping 中的值将 skb 指向频带和队列。在基本驱动程序中使用此字段来确定将 skb 发送到哪个队列。
已经添加了 sch_multiq,用于希望避免队首阻塞的硬件。它将循环遍历频带,并在取消数据包排队之前验证与该频带关联的硬件队列是否已停止。
在 qdisc 加载时,频带的数量基于硬件上的队列数量。一旦建立关联,任何设置了 skb->queue_mapping 的 skb 都将被排队到与硬件队列关联的频带。
第 3 节:使用 MULTIQ 进行多队列设备的简要指南¶
userspace 命令 “tc”(iproute2 包的一部分)用于配置 qdisc。 要将 MULTIQ qdisc 添加到您的网络设备,假设该设备名为 eth0,请运行以下命令
# tc qdisc add dev eth0 root handle 1: multiq
qdisc 将分配频带的数量,使其等于设备报告的队列数量,并将 qdisc 联机。 假设 eth0 有 4 个 Tx 队列,则频带映射将如下所示
band 0 => queue 0
band 1 => queue 1
band 2 => queue 2
band 3 => queue 3
流量将开始通过每个队列流动,基于 simple_tx_hash 函数或基于您定义的 netdev->select_queue()。
tc 过滤器的行为保持不变。 但是,添加了一个新的 tc 动作 skbedit。 假设您想通过特定队列将所有流量路由到特定主机,例如 192.168.0.3,您可以使用此操作并建立一个如下的过滤器
tc filter add dev eth0 parent 1: protocol ip prio 1 u32 \
match ip dst 192.168.0.3 \
action skbedit queue_mapping 3
- 作者:
Alexander Duyck <alexander.h.duyck@intel.com>
- 原始作者:
Peter P. Waskiewicz Jr. <peter.p.waskiewicz.jr@intel.com>