多队列网络设备支持 HOWTO¶
第 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 进行多队列设备的简要 HOWTO¶
用户空间命令“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>