輪詢模式驅動程序(Poll Mode Driver,PMD)線程負責處理DPDK數據路徑上的大部分工作,並執行諸如輸入端口的連續輪詢等任務。一旦接收到數據包及對其進行分類,分類完成後進行處理動作。
PMD線程使用接收(RX)和發送(TX)隊列,通常稱爲rxqs和txqs。TX隊列的配置自動產生,RX隊列可以由用戶進行配置。這可以通過以下兩種方式之一實現:
-
對於物理接口,配置通過工具
ovs-appctl
實現. -
對於虛擬接口,配置也是通過工具
ovs-appctl
實現,但是此配置必須反映在客戶機的配置中(例如,QEMU的命令行參數)。
ovs-appctl
工具也提供一些命令查詢PMD線程以及相關隊列信息,以下討論這些。
PMD線程統計
顯示當前統計信息:
$ ovs-appctl dpif-netdev/pmd-stats-show
清除統計信息:
$ ovs-appctl dpif-netdev/pmd-stats-clear
分配到PMD線程的端口/RX隊列
PMD線程及其使用的RX隊列需要正確配置,以便達到最大的性能。這一點尤其正確對於啓用諸如multipqueue之類的功能的物理接口dpdk phy multipqueue和vhost用戶接口dpdk vhost user。
顯示端口/RX隊列分配情況:
$ ovs-appctl dpif-netdev/pmd-rxq-show
RX隊列可能手動固定在某個核心上。這將改變默認的到PMD線程的RX隊列分配:
$ ovs-vsctl set Interface <iface> \
other_config:pmd-rxq-affinity=<rxq-affinity-list>
where:
<rxq-affinity-list>
表示CSV格式列表:<queue-id>:<core-id>
。
例如:
$ ovs-vsctl set interface dpdk-p0 options:n_rxq=4 \
other_config:pmd-rxq-affinity="0:3,1:7,3:8"
以上命令設置 4 個RX隊列,配置如下:
- 隊列 #0 固定在覈心3
- 隊列 #1 固定在覈心7
- 隊列 #2 未固定
- 隊列 #3 固定在覈心8
RX隊列被固定的核心上運行的PMD線程將處於隔離狀態。這意味着該線程只能輪詢被固定的RX隊列。
警告:
如果不存在未隔離的PMD線程,未固定的RX隊列將得不到輪詢。同樣,如果參數中要求固定的核心<core-id>
不可用(例如,<core-id>
不在pmd-cpu-mask
掩碼內),相應的RX隊列也不會被任何PMD線程的輪詢。
如果沒有未RX隊列指定pmd-rxq-affinity
參數, 它們將自動的分配到PMDs線程(核心)。
爲PMDs線程自動分配RXQs的算法可由以下命令設置:
$ ovs-vsctl set Open_vSwitch . other_config:pmd-rxq-assign=<assignment>
默認情況下,使用cycles
分配法,即首先將每個RXQs隊列按照測量的處理週期排序,之後以降序方式公平的分配到PMDs線程,如果PMD線程數量小於隊列數量,分配過程將以多輪次完成(由上到下,再由下到上). 例如,5個接收隊列和3個核心 - 3,7和8. 最近一個時間間隔在每個隊列上測量到的核心週期使用情況如下:
- 隊列 #0: 30%
- 隊列 #1: 80%
- 隊列 #3: 60%
- 隊列 #4: 70%
- 隊列 #5: 10%
RX接收隊列將以如下的次序分配到核心上:
- Core 3: Q1 (80%) |
- Core 7: Q4 (70%) | Q5 (10%)
- Core 8: Q3 (60%) | Q0 (30%)
另外, 也可以使用roundrobin
分配法,即以循環方式將RXQs隊列分配到PMDs進程. 在OVS 2.9版本前,這是默認使用的分配算法. 例如, 有以下的端口和隊列:
- 端口 #0 隊列 #0 (P0Q0)
- 端口 #0 隊列 #1 (P0Q1)
- 端口 #1 隊列 #0 (P1Q0)
- 端口 #1 隊列 #1 (P1Q1)
- 端口 #1 隊列 #2 (P1Q2)
RX隊列可能以如下的次序分配到核心上:
Core 3: P0Q0 | P1Q1
Core 7: P0Q1 | P1Q2
Core 8: P1Q0 |
查看關於每個RX隊列佔用的PMD核心週期數,在當下測量出來的佔用歷史信息:
$ ovs-appctl dpif-netdev/pmd-rxq-show
注意:
爲每個RX隊列記錄和顯示一分鐘的歷史記錄,以允許流量模式高峯。由於流量模式或重新配置,所引起的RX隊列的PMD核心週期的任何更改,需要一分鐘才能完全反映在統計數據中。
每當配置發生更改,或者通過以下命令的執行,都將觸發RX隊列到PMD線程的分配變動:
$ ovs-appctl dpif-netdev/pmd-rxq-rebalance
pmd-rxq-show
命令於OVS 2.6.0版本加入。
基於利用率的RX隊列到PMD的分配和pmd-rxq-rebalance
命令添加於OVS 2.9.0。在此之前,分配採用循環方法,沒有考慮處理週期。
此外,pmd-rxq-show
命令的輸出被修改爲包括以百分比表示的PMD的RX隊列利用率。在此之前,跟蹤統計數據是不可行的。
自動分配到PMD線程的端口/RX隊列 (實驗性質)
基於週期或利用率的RX隊列分配到PMD線程可以提高負荷分佈效率,但不適應隨時間變化的流量模式。這會導致PMD之間的負載不均勻,從而導致總體吞吐量的降低。
爲解決此問題,可啓用PMD自動負載均衡:
$ ovs-vsctl set open_vswitch . other_config:pmd-auto-lb="true"
如果pmd-auto-lb設置爲true,並且啓用了基於週期的分配方法,如果存在2個或多個非隔離的PMD線程,其中至少一個PMD正在輪詢多個RX隊列,自動負載均衡將啓用。所以,需要滿足以下條件才能啓用自動負載均衡:
- RX隊列到PMD的基於週期的分配已啓用.
- pmd-auto-lb參數設置爲true.
- 存在兩個或多個非隔離PMD線程.
- 並且至少一個非隔離的PMD線程具有多個輪詢隊列.
如果不滿足上述任一條件,則禁用PMD自動負載均衡。
一旦設置了自動負載均衡,每個非隔離PMD都會每10秒鐘測量一次其每個關聯隊列的處理負荷。如果PMD連續6個間隔的合併負荷達到95%,PMD認爲自己已經過載。
如果任一PMD進程過載,OVS主線程執行PMD分配算法的預檢運行。預檢運行不會更改現有隊列的PMD分配。
如果預檢運行的結果表明負荷分佈的提升,將執行實際重新分配。
注意:
如果隊列在不同NUMA節點分配,則PMD自動負載均衡當前不起作用,因爲與預檢的預測相比實際處理負荷可能會變得更糟。
兩個連續的PMD自動負載均衡操作之間的最短時間可可通過以下方式配置:
$ ovs-vsctl set open_vswitch .\
other_config:pmd-auto-lb-rebal-interval="<interval>"
參數<interval>
的單位爲分鐘. 默認間隔爲1分鐘,設置爲0意味值恢復1分鐘的默認值。
用戶可以使用此選項避免頻繁觸發PMD自動負載均衡。例如,設置此值(以分鐘爲單位),使其在幾小時,一週或一天內發生一次。
注意:
在某些場景下,可能不希望自動負載均衡觸發。例如,如果特定RX隊列的流量模式頻繁的變化,並且由於dpctl和EMC中對新添加流的更改,將打亂處理器緩存。在這種情況下,用戶應該相應地配置重新均衡間隔避免頻繁的再均衡發生。