关于 DPDK 的 一些零散的杂言杂语的念头/看法
回顧了之前 DPDK 的一些學習。有一些零散的雜言雜語的念頭/看法,原本分散在各處,之前沒有記錄下來。這里簡單記錄補充一下。
===============================================================================================================
@@@ #1. DPDK 的各種 API subset 的定義,肯定是從 通用性的角度 來定義,目標是 “期望盡量generic,定義一些common framework,期望所有 NIC / PMD 都盡量遵循 這些common framework的定義”。但是,這種 “期望”,有時可能會造成一些理解和使用上的混亂。
---------------------------------------------------------------------------------------------------------------
--- 例子 #1. Generic flow API (rte_flow)
?? ?這個 API subset 的 common framework 所定義的模型是:
?? ??? ?期望 NIC 內部有一個 硬件上的 HW component "flow engine"(__邏輯上的定義,名字隨意),可以對其配置 flow rules。
?? ??? ?一條 flow rule = matching items + actions。 其中,matching items 是定義了 packet metadata(__比如說,5-tuple,VLAN, 等等 )。?
?? ??? ??? ??? ?#
?? ??? ??? ??? ?# --- 注意 flow rule 在 DPDK framework 中的結構體定義,是 generic 的,但具體配置到 NIC flow engine 時,會被 NIC/PMD “翻譯”為 NIC-specific 的格式。
?? ??? ??? ??? ?#
?? ??? ?對 ingress / egress packets, "flow engine" 在硬件上的處理是,根據 flow rules table,對 packets 判斷其是屬于哪一條 flow rule,并執行 rule 中的 actions。
?? ?問題在于:
?? ??? ?并不是所有 NIC 都會有一個 HW component "flow engine"。?? ??? ?# 或者,沒有明顯的 "flow engine"。
?? ??? ?并不是所有 有"flow engine",都支持 common framework 所定義的 全部 matching items types 和 actions types。
?? ?------------------------------------------------------
?? ?比如說:
?? ??? ?
?? ??? ?Marvell PPv2 (Packet Processor v2) 1/10 Gbps adapter?? ?# 見: << Network Interface Controller Drivers---nics >> / Chapter 36. MVPP2 POLL MODE DRIVER?? ??? ?
?? ??? ??? ?我手頭上并沒有 MVPP2 的 datasheet。但是之前做過 基于 Marvell xCat switch chip 的交換機項目,知道 Marvell 的網卡,一般會有 "Policy Engine", "Tunnel-Termination", "Tunnel-Start"(__這些都是 Marvell datasheet 中本身的名字,可以認為它們共同算作 Marvell NIC 的 "flow engine" )。
?? ??? ??? ?從 Marvell NIC 所支持的硬件能力來看,其是可以:
?? ??? ??? ??? ??? ?對 匹配 matching items 的 tunnel packet,進行 DECAP,得到 inner packet。
?? ??? ??? ??? ??? ?或者,對匹配 matching items 的 non-tunnel packet,進行 ENCAP,得到 tunnel packet .
?? ??? ??? ?
?? ??? ?Marvell NIC 所支持的 tunnel protocol,又并不是 DPDK 所定義的。
?? ??? ?DPDK rte_flow framework,定義了這些 tunnel 相關的 flow action:
?? ??? ??? ?RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP
?? ??? ??? ?RTE_FLOW_ACTION_TYPE_VXLAN_DECAP
?? ??? ??? ?RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP?? ??? ?# 字面縮寫好像是 "Next Version GRE"
?? ??? ??? ?RTE_FLOW_ACTION_TYPE_NVGRE_DECAP?? ??? ?# --- 但實際上是 Network Virtualization using Generic Routing Encapsulation (NVGRE)
?? ??? ??? ?... 等等。
?? ??? ?而 Marvell NIC (__我只提我看到過的 ) 只支持 GRE tunnel 和 MPLS tunnel。
?? ??? ?所以,在 DPDK 中的 MVPP2 PMD,就不支持 DPDK rte_flow framework 的 這些 tunnel 相關的 flow actions。
?? ??? ??? ?--- <tip>: 可能目前看到的,就只有 /drivers/net/mlx5/ 對 tunnel flow actions 支持得比較好。
?? ?------------------------------------------------------
?? ?又比如說:
?? ??? ?Intel e1000 或者 ixgbe 或者 i40e。
?? ??? ?它們 datasheet 中,并沒有明確提到 "flow engine" 這么一個 HW component。
?? ??? ?但是有 "flow redirector" (FDIR) 和其他各種 filter tables。
?? ??? ?
?? ??? ?注意,它們的 "flow redirector" (FDIR) 和 "filter tables" 的大致功能是: 對匹配的 packets,進行 drop 或者 multi-rxq-assignment (__即,enqueue 到不同的 rx_ring 中 )。
?? ??? ?所以,它們的 PMD 中對 DPDK rte_flow framework 的支持,?? ??? ?# igb_flow.c, ixgbe_flow.c, i40e_flow.c
?? ??? ?基本上只支持這些 action types:
?? ??? ??? ?RTE_FLOW_ACTION_TYPE_DROP
?? ??? ??? ?RTE_FLOW_ACTION_TYPE_QUEUE?? ??? ??? ?# enqueue 到不同的 rx_ring 中
?? ??? ?rte_flow framework 所定義的大部分其他 action types,都不支持。
?? ?------------------------------------------------------
?? ?從 DPDK programming 使用 Generic flow API (rte_flow) 的角度來看,
?? ??? ?#a. 需要 熟悉 underlying NIC / PMD,它們 對 rte_flow 的支持如何,支持哪些內容,不支持哪些內容。
?? ??? ??? ?
?? ??? ??? ?需要看一看 underlying PMD 的 xxx_flow.c 和 datasheet。
?? ??? ?#b. 依賴 rte_flow API,判斷 underlying NIC / PMD 是否支持一條 flow rule
?? ??? ??? ??? ?/* Check whether a flow rule can be created on a given port. */
?? ??? ??? ??? ?int
?? ??? ??? ??? ?rte_flow_validate(uint16_t port_id,
?? ??? ??? ??? ??? ??? ? ?const struct rte_flow_attr *attr,
?? ??? ??? ??? ??? ??? ? ?const struct rte_flow_item pattern[],
?? ??? ??? ??? ??? ??? ? ?const struct rte_flow_action actions[],
?? ??? ??? ??? ??? ??? ? ?struct rte_flow_error *error)?? ??? ??? ??
?? ??? ??? ?其內部會調用不同 PMD 的 xxx_flow.c 的 xxx_flow_validate(),進行判斷和檢查,比如說:
?? ??? ??? ??? ?igb_flow_validate()
?? ??? ??? ??? ?ixgbe_flow_validate()
?? ??? ??? ??? ?i40e_flow_validate()
?? ??? ??? ?檢查支持的話,再去實際地配置 flow rule。
?? ??? ??? ??? ?/* Create a flow rule on a given port. */
?? ??? ??? ??? ?struct rte_flow *
?? ??? ??? ??? ?rte_flow_create(uint16_t port_id,
?? ??? ??? ??? ??? ??? ?const struct rte_flow_attr *attr,
?? ??? ??? ??? ??? ??? ?const struct rte_flow_item pattern[],
?? ??? ??? ??? ??? ??? ?const struct rte_flow_action actions[],
?? ??? ??? ??? ??? ??? ?struct rte_flow_error *error)
?? ?------------------------------------------------------
?? ??? ?
---------------------------------------------------------------------------------------------------------------
===============================================================================================================
@@@ #2. DPDK API中,有一些 API subset 在其 文檔 上并沒有描述得很清楚,比如說,沒有說明白 這些 API subset 是和NIC硬件上相關 或者是 純粹的軟件上實現的邏輯,可能會造成一些理解和使用上的混亂。?? ?---?? ?需要自己理清楚,來判斷在實際工作中,是否適合使用。
---------------------------------------------------------------------------------------------------------------
--- 例子 #1. QoS 相關的內容。?? ??? ?# 是相當混亂的一部分內容。
?在 DPDK 中,QoS 大概有這些內容(__以他們相關的頭文件):?? ??? ?# 見文檔: << Programmer's Guide---prog_guide >>
?? ?ingress:?? ??? ?# 主要是 metering 和 policing
?? ??? ?<rte_mtr.h>
?? ??? ?<rte_meter.h>, <rte_policer.h>?? ??? ?# 見 文檔 / 14. Traffic Metering and Policing API
?? ?egress:?? ??? ??? ?# 主要是 scheduling
?? ?
?? ??? ?<rte_tm.h>?? ??? ?# 見 文檔 / 15. Traffic Management API
?? ??? ?<rte_sched.h>?? ?# 見 文檔 / 44. Quality of Service (QoS) Framework
?這4者之間的關聯關系是: ....... 沒有任何關聯關系。?? ?
?--- 所以,很容易在理解和使用上造成混亂。
?? ?------------------------------------------------------
?? ?ingress <rte_mtr.h>
?? ??? ?是 通過 Generic flow API (rte_flow) (__上面提到過的)來使用。配置 flow rule 的 action type:
?? ??? ??? ??? ?RTE_FLOW_ACTION_TYPE_METER
?? ??? ?讓 NIC 硬件中的 "flow engine",對 匹配的 packets 進行 metering / policing。
?? ??? ?--- 即,metering / policing 邏輯,是由 NIC 硬件上來做的。
?? ??? ??? ?但注意,并不是所有 NIC/PMD,都支持 這個 RTE_FLOW_ACTION_TYPE_METER。?? ?# 只有少數才支持。
?? ?------------------------------------------------------
?? ?ingress <rte_meter.h>, <rte_policer.h>
?? ??? ?和 NIC 硬件沒有關系。完全是一個 軟件上的 API subset。
?? ??? ?--- 在 軟件上,由 CPU 來執行 執行 metering/policing 的邏輯。
?? ?
?? ?------------------------------------------------------
?? ?ingress <rte_mtr.h> 和 <rte_meter.h>, <rte_policer.h> 之間的關聯關系是: 沒有關系。
?? ?------------------------------------------------------
?? ?egress <rte_tm.h>
?? ??? ?大致功能是,配置 NIC 硬件上的 multi-tx-queue 的 weight, RED policy, shaper rate limiting 等。
?? ??? ?其定義了 node hierarchy 的模型。
?? ??? ??? ?這個模型是多層次的,其中 leaf node 對應一條 HW tx-queue。
?? ??? ?不同的 NIC/PMD 所支持的層次數量,和 具體的層次定義,并不相同。
?? ?
?? ??? ??? ?比如說:
?? ?
?? ??? ??? ??? ??? ?ixgbe: port / tc / queue?? ??? ?# 三層?? ??? ?# ixgbe_tm.c
?? ?
?? ?
?? ??? ??? ??? ??? ?mvpp: root / queue?? ??? ??? ??? ?# 二層?? ??? ?# mrvl_tm.c
?? ??? ??? ??? ?
?? ??? ??? ?
?? ??? ??? ??? ??? ?octecon: root / sch1 / sch2 / sch3 / sch4 / queue?? ?# 好多層,搞不明白?? ?# otx_tm.c
?? ??? ?node hierarchy模擬的通用定義是: (__我猜想的),指定不同層次 的 weight, RED policy, shaper rate limiting。
?? ??? ?但 NIC / PMD 的實際支持,可能 就只是: 對 HW tx-queue 設置 rate limiting,而已。
?? ??? ??? ?比如說:
?? ??
?? ??? ??? ??? ??? ?ixgbe: ixgbe_hierarchy_commit()?? ??? ?# 其并不對 port / tc 進行什么設置,只是設置 queue 的 rate limit。
?? ??? ?
?? ?------------------------------------------------------
?? ?egress <rte_sched.h>
?? ??? ?純軟件的 SW-level 的 API subset,和 NIC 硬件上的 hw_tx_ring scheduling 沒有任何關系。
?? ??? ?其所定義的 5-level tree hierarchy,和 上面 <rte_tm.h> 定義的 node hierarchy,沒有任何關系。
?? ??? ?<rte_sched.h> 和 Linux tc ( Qdisc ) 相似:
?? ??? ??? ?在 packet TX 時,將 egress packets 給 enqueue 到 hierarchy 中 進行排隊什么的,然后從 hierarchy 中 dequeue 一些 packets 進行 actual TX。
?? ?------------------------------------------------------
?? ?egress <rte_tm.h> 和 <rte_sched.h> 之間的關聯關系是: 沒有關系。
?? ?
?? ?------------------------------------------------------
---------------------------------------------------------------------------------------------------------------
--- 例子 #2. Bond
?? ?見: << Programmer's Guide---prog_guide >> / 22. Link Bonding Poll Mode Driver Library
?? ?大部分 switch chip,都支持 將多個 ports 組成一個 bond ports 的,這是硬件上的功能。
?? ?而 DPDK 的 bonding PMD,完全是軟件上的功能。?? ??? ??? ?# 和 Linux bonding framework 一樣。
?? ?不過,DPDK 文檔上一開始就說明白了,是 "pure-software library":
?? ??? ?DPDK also includes a pure-software library that allows physical PMDs to be bonded together to create a single logical PMD.
---------------------------------------------------------------------------------------------------------------
--- 例子 #3. <rte_flow_classifier.h>?? ??? ?# 見 << Programmer's Guide---prog_guide >> / 29. Flow Classification Library
?? ?<< Programmer's Guide---prog_guide >>?
?? ??? ?/ 12. Generic flow API (rte_flow)?? ??? ?# <rte_flow.h>
?? ??? ?/ 29. Flow Classification Library?? ??? ?# <rte_flow_classifier.h>
?? ?
?這兩者的關系是: ..... 基本沒有關系。
?<rte_flow.h> (__前面提到過的),是去配置 NIC 硬件中的 "flow engine" 的 flow rules。
?<rte_flow_classifier.h>,則是:
?? ??? ?完全是在 SW-level 實現的 library。和 low-level PMD 和 NIC 都無關。
?? ??? ?之所以 在名字上叫做 "flow",是因為它“借用”了 <rte_flow.h> 定義的 data structure:
?? ??? ??? ??? ? ? const struct rte_flow_attr *attr,
?? ??? ??? ??? ? ? const struct rte_flow_item pattern[],
?? ??? ??? ??? ? ? const struct rte_flow_action actions[],
?? ??? ?其 classify 邏輯的執行,也完全是由 DPDK app 顯式地調用 API:
?? ??? ??? ??? ??? ?rte_flow_classifier_query()?
?? ??? ?來進行的。 --- 在 SW-level 執行。
?? ??? ?它 到底是做什么用的呢?
?? ??? ??? ?The initial implementation supports counting of IPv4 5-tuple packets which match a particular Flow rule only.
?? ??? ??? ?--- 也就是說,當前的功能,只是: ?在 SW-level,對 匹配 flow match patterns 的 packets,進行 counting。 --- 統計計數而已。
?? ??? ??? ??? ?
---------------------------------------------------------------------------------------------------------------
===============================================================================================================
@@@ #3. 對于 DPDK 的 spinlock / rwlock 和 RCU
---------------------------------------------------------------------------------------------------------------
spinlock / rwlock
?? ?Linux kernel 的 API 是:
?? ??? ?spin_lock() / spin_unlock()
?? ??? ?spin_lock_bh() / spin_unlock_bh()
?? ??? ?spin_lock_irqsave() / spin_unlock_irqrestore()
?? ?而 DPDK API 只是:
?? ??? ?rte_spinlock_lock() / rte_spinlock_unlock()
?? ?他們內部都是 使用 CPU 的 atomic_compare_exchange ( CAS ) instructions 來實現的。
?? ?
?? ?不過,Linux 會 關閉 preemption / bh / irq。
?? ?但 DPDK locking 為什么不在意 preemption / bh / irq ?
?? ??? ?#1. 因為 DPDK 是 user-level programming,沒有 bh。
?? ??? ??? ?至于 irq .... DPDK 也關閉了 NIC 的 rx-tx irq,只是進行 polling。
?? ??? ?#2. 至于 preemption ..... 和 DPDK 的 lcore (__或者說 multi-thread model )定義有關。
?? ??? ??? ?一個 DPDK application,只允許,一個 CPU core 運行一個 thread。
?? ??? ??? ?不會有 2 個 DPDK thread 運行在同一個 CPU 上的情況。
?? ??? ??? ?--- 以上限制,是由 DPDK EAL layer,在代碼上施加的(__通過 pthread_set_affinity() )。
---------------------------------------------------------------------------------------------------------------
RCU
?? ?Linux kernel RCU 的 quiescent state 的條件是:?? ??? ??? ?# 不精確,但大致是這樣理解。
?? ??? ?所有 CPU 都返回 user-level 一次。?? ?# 這樣,所有CPU 原本的 kernel-level stack 都被“清空”了。
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?#
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?# 再進入 kernel-level 的 代碼,是無法從 kernel-level stack 中
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?# 或者 kernel list/hlist 等datastructure 中,再獲得?
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?# 需要RCU defered free 的 數據的 “指針引用”。
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?#
?? ??? ?然后,RCU 的 defered free,會自動由 RCU layer 來進行。
?? ??? ?所以,并不需要 kernel code,自己來檢查和“報告” RCU quiescent state。
?? ?而 DPDK RCU,需要 application 本身來調用 DPDK RCU API,來 檢查和“報告” RCU quiescent state。
?? ?所以,會比 Linux kernel RCU 的用法,麻煩和繞一些(__很多)。
---------------------------------------------------------------------------------------------------------------
===============================================================================================================
?
總結
以上是生活随笔為你收集整理的关于 DPDK 的 一些零散的杂言杂语的念头/看法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 云吸猫时代的“脱单密码”
- 下一篇: 支付宝小程序如何在{{}}中使用函数方法