多佇列網路裝置支援指南

第 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>