DPDK編程指南(翻譯)(七)

7.輪詢(xún)模式驅(qū)動(dòng)

DPDK包括1Gigabit、10Gigabit 及 40Gigabit 和半虛擬化IO的輪詢(xún)模式驅(qū)動(dòng)程序。

輪詢(xún)模式驅(qū)動(dòng)程序(PMD)由通過(guò)在用戶(hù)空間中運(yùn)行的BSD驅(qū)動(dòng)提供的API組成,以配置設(shè)備及它們的隊(duì)列。此外,PMD直接訪問(wèn) RX 和 TX 描述符,且不會(huì)有任何中斷(鏈路狀態(tài)更改中斷除外)產(chǎn)生,這可以保證在用戶(hù)空間應(yīng)用程序中快速接收,處理和傳送數(shù)據(jù)包。本節(jié)介紹PMD的要求、設(shè)計(jì)原則和高級(jí)架構(gòu),并介紹了以太網(wǎng)PMD的對(duì)外通用API。

7.1.前提與假設(shè)

DPDK環(huán)境支持兩種模式的數(shù)據(jù)包處理,RTC模式和pipeline模式:

  • 在 run-to-completion 模式中,通過(guò)調(diào)用API來(lái)輪詢(xún)指定端口的RX描述符以獲取報(bào)文。 緊接著,在同一個(gè)core上處理報(bào)文,并通過(guò)API調(diào)用將報(bào)文放到接口的TX描述符中以發(fā)送報(bào)文。
  • 在 pipe-line 模式中,一個(gè)core輪詢(xún)一個(gè)或多個(gè)接口的RX描述符以獲取報(bào)文。然后報(bào)文經(jīng)由ring被其他core處理。其他core可以繼續(xù)處理報(bào)文,最終報(bào)文被放到TX描述符中以發(fā)送出去。

在同步的run-to-complete模式中,每個(gè)邏輯核處理數(shù)據(jù)包的流程包括以下步驟:

  • 通過(guò)PMD報(bào)文接收API來(lái)獲取報(bào)文
  • 一次性處理每個(gè)數(shù)據(jù)報(bào)文,直到轉(zhuǎn)發(fā)階段
  • 通過(guò)PMD發(fā)包API將報(bào)文發(fā)送出去

相反地,在異步的pipeline模式中,一些邏輯核可能專(zhuān)門(mén)用于接收?qǐng)?bào)文,其他邏輯核用于處理前面收到的報(bào)文。收到的數(shù)據(jù)包通過(guò)報(bào)文ring在邏輯核之間交換。數(shù)據(jù)包收包過(guò)程包括以下步驟:

  • 通過(guò)PMD收包API獲取報(bào)文
  • 通過(guò)數(shù)據(jù)包隊(duì)列向邏輯核提供接收到的數(shù)據(jù)包

數(shù)據(jù)包處理過(guò)程包括以下步驟:

  • 從數(shù)據(jù)包隊(duì)列中獲取數(shù)據(jù)包
  • 處理接收到的數(shù)據(jù)包,直到重新發(fā)送出去

為了避免任何不必要的中斷處理開(kāi)銷(xiāo),執(zhí)行環(huán)境不得使用任何異步通知機(jī)制。即便有需要,也應(yīng)該盡量使用ring來(lái)引入通知信息。

在多核環(huán)境中避免鎖競(jìng)爭(zhēng)是一個(gè)關(guān)鍵問(wèn)題。為了解決這個(gè)問(wèn)題,PMD旨在盡可能地使用每個(gè)core的私有資源。例如,PMD每個(gè)端口維護(hù)每個(gè)core單獨(dú)的傳輸隊(duì)列。同樣的,端口的每個(gè)接收隊(duì)列都被分配給單個(gè)邏輯核并由其輪詢(xún)。

為了兼容NUMA架構(gòu),內(nèi)存管理旨在為每個(gè)邏輯核分配本地(相同插槽)中的專(zhuān)用緩沖池,以最大限度地減少遠(yuǎn)程內(nèi)存訪問(wèn)。數(shù)據(jù)包緩沖池的配置應(yīng)該考慮到DIMMs、channels和ranks等底層物理內(nèi)存架構(gòu)。應(yīng)用程序必須確保在內(nèi)存池創(chuàng)建時(shí)給出合適的參數(shù)。具體內(nèi)容參閱內(nèi)存池庫(kù)。

7.2.設(shè)計(jì)原則

Ethernet* PMDs的API和架構(gòu)設(shè)計(jì)遵考慮到以下原則。

PMDs必須能夠幫助上層的應(yīng)用實(shí)現(xiàn)全局的策略。反之,不能阻止或妨礙上層應(yīng)用的實(shí)施。

例如,PMD的發(fā)送和接收函數(shù)都有大量的報(bào)文或描述符需要輪詢(xún)。這允許RTC處理協(xié)議棧通過(guò)不同的全局循環(huán)策略靜態(tài)修護(hù)或動(dòng)態(tài)調(diào)整其行為如:

  • 立即接收,處理并以零碎的方式一次傳送數(shù)據(jù)包。
  • 盡可能所的接收數(shù)據(jù)包,然后處理所有數(shù)據(jù)包,再發(fā)送。
  • 接收給定的最大量的數(shù)據(jù)包,處理接收的數(shù)據(jù)包,累加,最后將累加的數(shù)據(jù)包發(fā)送出去。

為了實(shí)現(xiàn)最優(yōu)性能,需要考考整體軟件設(shè)計(jì)選擇和純軟件優(yōu)化技術(shù),并與可用的低層次硬件優(yōu)化功能(如CPU緩存屬性、總線速度、NIC PCI帶寬等)進(jìn)行考慮和平衡。報(bào)文傳輸?shù)那闆r就是突發(fā)性網(wǎng)絡(luò)報(bào)文處理是軟硬件權(quán)衡問(wèn)題的一個(gè)例子。 在初始情況下,PMD只能導(dǎo)出一個(gè) rte_eth_tx_one 函數(shù),以便在給定的隊(duì)列上一次傳輸一個(gè)數(shù)據(jù)包。最重要的是,可以輕松構(gòu)建一個(gè) rte_eth_tx_burst 函數(shù),循環(huán)調(diào)用 rte_eth_tx_one 函數(shù)以便一次傳輸多個(gè)數(shù)據(jù)包。然而,PMD有效地實(shí)現(xiàn)了 rte_eth_tx_burst 函數(shù),以通過(guò)以下優(yōu)化來(lái)最小化每個(gè)數(shù)據(jù)包的驅(qū)動(dòng)級(jí)傳輸開(kāi)銷(xiāo):

  • 在多個(gè)數(shù)據(jù)包之間共享調(diào)用 rte_eth_tx_one 函數(shù)的非攤銷(xiāo)成本。
  • 啟用 rte_eth_tx_burst 函數(shù)以利用burst-oriented 硬件特性(緩存數(shù)據(jù)預(yù)取、使用NIC頭/尾寄存器)以最小化每個(gè)數(shù)據(jù)包的CPU周期數(shù), 例如,通過(guò)避免對(duì)環(huán)形緩傳輸描述符的不必要的讀取寄存器訪問(wèn),或通過(guò)系統(tǒng)地使用精確匹配告訴緩存行邊界大小的指針數(shù)組。
  • 使用burst-oriented軟件優(yōu)化技術(shù)來(lái)移除失敗的操作結(jié)果,如ring索引的回滾。

還通過(guò)API引入了Burst-oriented函數(shù),這些函數(shù)在PMD服務(wù)中密集使用。這些函數(shù)特別適用于NIC ring的緩沖區(qū)分配器,他們提供一次分配/釋放多個(gè)緩沖區(qū)的功能。例如,一個(gè) mbuf_multiple_alloc 函數(shù)返回一個(gè)指向rte_mbuf 緩沖區(qū)的指針數(shù)組,它可以在向ring添加多個(gè)描述符來(lái)加速PMD的接收輪詢(xún)功能。

7.3.邏輯核、內(nèi)存和網(wǎng)絡(luò)接口卡隊(duì)列的關(guān)系

當(dāng)處理器的邏輯核和接口利用其本地存儲(chǔ)時(shí),DPDK提供NUMA支持,以提供更好的性能。因此,與本地PCIE接口相關(guān)的mbuf分配應(yīng)從本地內(nèi)存中創(chuàng)建的內(nèi)存池中申請(qǐng)。如果可能,緩沖區(qū)應(yīng)該保留在本地處理器上以獲取最佳性能,并且應(yīng)使用從本地內(nèi)存中分配的mempool中申請(qǐng)的mbuf來(lái)填充RX和TX緩沖區(qū)描述符。

如果數(shù)據(jù)包或數(shù)據(jù)操作在本地內(nèi)存中,而不是在遠(yuǎn)程處理器內(nèi)存上,則RTC模型也會(huì)運(yùn)行得更好。 只要所有使用的邏輯核位于同一個(gè)處理器上,pipeline模型也將獲得更好的性能。

所個(gè)邏輯核不應(yīng)共享接口的接收或發(fā)送隊(duì)列,因?yàn)檫@將需要全局上鎖保護(hù),而導(dǎo)致性能下降。

7.4.設(shè)備標(biāo)識(shí)和配置

7.4.1.設(shè)備標(biāo)識(shí)

每個(gè)NIC端口(總線/橋、設(shè)備、功能)由其PCI標(biāo)識(shí)符唯一指定。該P(yáng)CI標(biāo)識(shí)符在DPDK初始化時(shí)執(zhí)行的PCI探測(cè)/枚舉功能分配。根據(jù)PCI標(biāo)識(shí)符,NIC端口被分配了兩個(gè)其他的表示:

  • 一個(gè)端口索引,用于在PMD API導(dǎo)出的所有函數(shù)中指定NIC端口
  • 端口名稱(chēng),用于在控制消息中指定端口,主要用于管理和調(diào)試目的。為了便于使用,端口名稱(chēng)包括端口索引。

7.4.2.設(shè)備配置

每個(gè)NIC端口的配置包括以下步驟:

  • 分配 PCI 資源
  • 將硬件復(fù)位為公知的默認(rèn)狀態(tài)
  • 設(shè)置PHY和鏈路
  • 初始化統(tǒng)計(jì)計(jì)數(shù)器

PMD API還必須導(dǎo)出函數(shù)用于啟動(dòng)/終止端口的全部組播功能,并且可以在混雜模式下設(shè)置/取消設(shè)置端口。

某些硬件卸載功能必須通過(guò)特定的配置參數(shù)在端口初始化時(shí)單獨(dú)配置。例如,接收側(cè)縮放(RSS)和數(shù)據(jù)中心橋接(DCB)功能就是這種情況。

7.4.3.即時(shí)配置

所有可以“即時(shí)”啟動(dòng)或停止的設(shè)備功能(即不停止設(shè)備),無(wú)需PMD API來(lái)導(dǎo)出函數(shù)實(shí)現(xiàn)這些功能。

所需要的是只是設(shè)備PCI寄存器的映射地址,以在驅(qū)動(dòng)程序之外使用特殊的函數(shù)來(lái)配置實(shí)現(xiàn)這些功能。

為此,PMD API導(dǎo)出一個(gè)函數(shù)提供可用于在驅(qū)動(dòng)程序外部設(shè)置給定設(shè)備功能的設(shè)備相關(guān)聯(lián)的所有信息。這些信息包括PCI供應(yīng)商標(biāo)識(shí)符,PCI設(shè)備標(biāo)識(shí)符,PCI設(shè)備寄存器的映射地址以及驅(qū)動(dòng)程序的名稱(chēng)。

這種方法的主要優(yōu)點(diǎn)是可以自由地選擇API來(lái)啟動(dòng)、配置、停止這些設(shè)備功能。

例如,testpmd應(yīng)用程序中的英特爾?82576千兆以太網(wǎng)控制器和英特爾?82599萬(wàn)兆以太網(wǎng)控制器控制器的IEEE1588功能配置。

可以以相同的方式配置端口的L3 / L4 5-Tuple包過(guò)濾功能等其他功能。以太網(wǎng)流控(暫停幀)可以在單個(gè)端口上進(jìn)行配置。有關(guān)詳細(xì)信息,請(qǐng)參閱testpmd源代碼。此外,只要數(shù)據(jù)包mbuf設(shè)置正確,就可以為單個(gè)數(shù)據(jù)包啟用網(wǎng)卡的L4(UDP / TCP / SCTP)校驗(yàn)和卸載。相關(guān)詳細(xì)信息,請(qǐng)參閱硬件offload 。

7.4.4.發(fā)送隊(duì)列配置

每個(gè)傳輸隊(duì)列都獨(dú)立配置了以下信息:

  • 發(fā)送環(huán)上的描述符數(shù)目
  • NUMA架構(gòu)中,用于標(biāo)識(shí)從哪個(gè)socket的DMA存儲(chǔ)區(qū)分配傳輸環(huán)的標(biāo)識(shí)
  • 傳輸隊(duì)列的Prefetch,Host及Write-Back閾值寄存器的值
  • 傳輸報(bào)文釋放的最小閾值。當(dāng)用于傳輸數(shù)據(jù)包的描述符數(shù)量超過(guò)此閾值時(shí),應(yīng)檢查網(wǎng)絡(luò)適配器以查看是否有回寫(xiě)描述符。在TX隊(duì)列配置期間可以傳遞0,以指示應(yīng)使用默認(rèn)值。tx_free_thresh的默認(rèn)值為32。這使得PMD不會(huì)去檢索完成的描述符,直到NIC已經(jīng)為此隊(duì)列處理了32個(gè)報(bào)文。
  • RS位最小閾值。在發(fā)送描述符中設(shè)置報(bào)告狀態(tài)(RS)位之前要使用的最小發(fā)送描述符數(shù)。請(qǐng)注意,此參數(shù)僅適用于Intel 10GbE網(wǎng)絡(luò)適配器。如果從最后一個(gè)RS位設(shè)置開(kāi)始使用的描述符數(shù)量(直到用于發(fā)送數(shù)據(jù)包的第一個(gè)描述符)超過(guò)發(fā)送RS位閾值(tx_rs_thresh),則RS位被設(shè)置在用于發(fā)送數(shù)據(jù)包的最后一個(gè)描述符上。簡(jiǎn)而言之,此參數(shù)控制網(wǎng)絡(luò)適配器將哪些傳輸描述符寫(xiě)回主機(jī)內(nèi)存。在TX隊(duì)列配置期間可以傳遞值為0,以指示應(yīng)使用默認(rèn)值。tx_rs_thresh的默認(rèn)值為32。這確保在網(wǎng)絡(luò)適配器回寫(xiě)最近使用的描述符之前至少使用32個(gè)描述符。這樣可以節(jié)省TX描述符回寫(xiě)所產(chǎn)生的上游PCIe *帶寬。重要的是注意,當(dāng)tx_rs_thresh大于1時(shí),應(yīng)將TX寫(xiě)回閾值(TX wthresh)設(shè)置為0。有關(guān)更多詳細(xì)信息,請(qǐng)參閱英特爾?82599萬(wàn)兆以太網(wǎng)控制器數(shù)據(jù)手冊(cè)。

對(duì)于tx_free_thresh和tx_rs_thresh,必須滿(mǎn)足以下約束:

  • tx_rs_thresh必須大于0。
  • tx_rs_thresh必須小于環(huán)的大小減去2。
  • tx_rs_thresh必須小于或等于tx_free_thresh。
  • tx_free_thresh必須大于0。
  • tx_free_thresh必須小于環(huán)的大小減去3。
  • 為了獲得最佳性能,當(dāng)tx_rs_thresh大于1時(shí),TX wthresh應(yīng)設(shè)置為0。

TX環(huán)中的一個(gè)描述符用作哨兵以避免硬件競(jìng)爭(zhēng)條件,因此是最大閾值限制。當(dāng)配置DCB操作時(shí),在端口初始化時(shí),發(fā)送隊(duì)列數(shù)和接收隊(duì)列數(shù)必須設(shè)置為128。

7.4.5.按要求釋放TX緩沖區(qū)

許多驅(qū)動(dòng)程序并沒(méi)有在數(shù)據(jù)包傳輸后立即將mbuf釋放回到mempool或本地緩存中。相反,他們將mbuf留在Tx環(huán)中,當(dāng)需要在Tx環(huán)中插入,或者 tx_rs_thresh 已經(jīng)超過(guò)時(shí),執(zhí)行批量釋放。

應(yīng)用程序請(qǐng)求驅(qū)動(dòng)程序通過(guò)接口 rte_eth_tx_done_cleanup() 釋放使用的mbuf。該API請(qǐng)求驅(qū)動(dòng)程序釋放不再使用的mbufs,而不管tx_rs_thresh值是否已超過(guò)。有兩種情況會(huì)使得應(yīng)用程序可能想要立即釋放mbuf:

  • 當(dāng)給定的數(shù)據(jù)包需要發(fā)送到多個(gè)目標(biāo)接口(對(duì)于第2層洪泛或第3層多播)。 一種方法是復(fù)制數(shù)據(jù)包或者復(fù)制需要操作的數(shù)據(jù)包頭部。 另一種方法是發(fā)送數(shù)據(jù)包,然后輪詢(xún) rte_eth_tx_done_cleanup() 接口直到報(bào)文引用遞減。 接下來(lái),這個(gè)報(bào)文就可以發(fā)送到下一個(gè)目的接口。 該應(yīng)用程序仍然負(fù)責(zé)管理不同目標(biāo)接口之間所需的任何數(shù)據(jù)包操作,但可以避免數(shù)據(jù)復(fù)制。 該API獨(dú)立于數(shù)據(jù)包是傳輸還是丟棄,只是mbuf不再被接口使用。
  • 一些應(yīng)用程序被設(shè)計(jì)為進(jìn)行多次運(yùn)行,如數(shù)據(jù)包生成器。 為了運(yùn)行的性能原因和一致性,應(yīng)用程序可能希望在每個(gè)運(yùn)行之間重新設(shè)置為初始狀態(tài),其中所有mbufs都返回到mempool。 在這種情況下,它可以為其已使用的每個(gè)目標(biāo)接口調(diào) rte_eth_tx_done_cleanup() API 以請(qǐng)求它釋放所有使用的mbuf。

要確定驅(qū)動(dòng)程序是否支持該API,請(qǐng)檢查 Network Interface Controller Drivers 文檔中的Free Tx mbuf on demand功能。

7.4.6.硬件offload

根據(jù) rte_eth_dev_info_get() 提供的驅(qū)動(dòng)程序功能,PMD可能支持硬件offload功能,如校驗(yàn)和TCP分段或VLAN插入。

這些offload功能的支持意味著將專(zhuān)用狀態(tài)位和值字段添加到rte_mbuf數(shù)據(jù)結(jié)構(gòu)中,以及由每個(gè)PMD導(dǎo)出的接收/發(fā)送功能的適當(dāng)處理。標(biāo)記列表及其精確含義在mbuf API文檔及報(bào)文緩沖區(qū)庫(kù)中元數(shù)據(jù)章節(jié)有描述。

7.5.輪詢(xún)模式驅(qū)動(dòng)API

7.5.1.概述

默認(rèn)情況下,PMD提供的所有外部函數(shù)都是無(wú)鎖函數(shù),這些函數(shù)假定在同一目標(biāo)設(shè)備上不會(huì)在不同的邏輯core上并行調(diào)用。例如,PMD接收函數(shù)不能再兩個(gè)邏輯核上并行調(diào)用,以輪詢(xún)相同端口的相同RX隊(duì)列。當(dāng)然,這個(gè)函數(shù)可以由不同的RX隊(duì)列上的不同邏輯核并行調(diào)用。上級(jí)應(yīng)用程序應(yīng)該保證強(qiáng)制執(zhí)行這條規(guī)則。

如果需要,多個(gè)邏輯核到并行隊(duì)列的并行訪問(wèn)可以通過(guò)專(zhuān)門(mén)的在線加鎖來(lái)顯式保護(hù),這些加鎖函數(shù)是建立在相應(yīng)的無(wú)鎖API之上的。

7.5.2.通用分組表示

數(shù)據(jù)包由數(shù)據(jù)結(jié)構(gòu) rte_mbuf 表示,這是一個(gè)包含所有必要信息的通用元數(shù)據(jù)結(jié)構(gòu)。這些信息包括與硬件特征相對(duì)應(yīng)的字段和狀態(tài)位,如IP頭部和VLAN標(biāo)簽的校驗(yàn)和。

數(shù)據(jù)結(jié)構(gòu)rte_mbuf包括以通用方式表示網(wǎng)絡(luò)控制器提供的硬件功能對(duì)應(yīng)的字段。對(duì)于輸入數(shù)據(jù)包,rte_mbuf 的大部分字段都由PMD來(lái)填充,包括接收描述符中的信息。相反,對(duì)于輸出數(shù)據(jù)包,rte_mbuf的大部分字段由PMD發(fā)送函數(shù)用于初始化發(fā)送描述符。

數(shù)據(jù)結(jié)構(gòu) mbuf 的更全面的描述,請(qǐng)參閱 Mbuf Library 章節(jié)。

7.5.3.以太網(wǎng)設(shè)備API

以太網(wǎng)PMD驅(qū)動(dòng)導(dǎo)出的以太網(wǎng)設(shè)備API請(qǐng)參閱 《DPDK API 參考手冊(cè)》 描述。

7.5.4.擴(kuò)展的統(tǒng)計(jì)API

擴(kuò)展的統(tǒng)計(jì)API允許每個(gè)獨(dú)立的PMD導(dǎo)出一組唯一的統(tǒng)計(jì)信息。每個(gè)統(tǒng)計(jì)信息狗有三個(gè)屬性:

  • Name:下文描述的用戶(hù)可讀的格式化字符串
  • Id:僅表示統(tǒng)計(jì)信息的整數(shù)
  • Value:一個(gè)無(wú)符號(hào)的64bit整數(shù),標(biāo)識(shí)統(tǒng)計(jì)結(jié)果

請(qǐng)注意,擴(kuò)展統(tǒng)計(jì)信息標(biāo)識(shí)符是驅(qū)動(dòng)程序特定的,因此對(duì)于不同的端口可能不一樣。API由各種rte_eth_xstats _*()函數(shù)組成,允許應(yīng)用程序靈活地檢索統(tǒng)計(jì)信息。

7.5.4.1.用戶(hù)可讀名稱(chēng)命名方案

對(duì)于暴露給API的客戶(hù)端的字符串,存在一個(gè)命名方案。這是為了允許刮取API用于感興趣的統(tǒng)計(jì)信息。命名方案使用由單個(gè)下劃線_分割的字符串。方案如下:

  • direction
  • detail 1
  • detail 2
  • detail n
  • unit

常規(guī)統(tǒng)計(jì)示例字符串如下,符合上面的方案:

  • rx_bytes
  • rx_crc_errors
  • tx_multicast_packets

該方案雖然簡(jiǎn)單,但可以靈活地顯示和讀取統(tǒng)計(jì)字符串中的信息。以下示例說(shuō)明了命名方案 rx_packets 的使用。 在這個(gè)例子中,字符串被分成兩個(gè)組件。第一個(gè) rx 表示統(tǒng)計(jì)信息與NIC的接收端相關(guān)聯(lián)。 第二個(gè) packets 表示測(cè)量單位是數(shù)據(jù)包。

一個(gè)更為復(fù)雜的例子是 tx_size_128_to_255_packets 。 在這個(gè)例子中, tx 表示傳輸, size 是第一個(gè)細(xì)節(jié), 128 等表示更多的細(xì)節(jié), packets 表示這是一個(gè)數(shù)據(jù)包計(jì)數(shù)器。

元數(shù)據(jù)中的一些方案補(bǔ)充如下:

  • 如果第一部分不符合 rx 或 tx ,統(tǒng)計(jì)計(jì)數(shù)器與傳送或接收不相關(guān)。
  • 如果第二部分的第一個(gè)字母是 q 且這個(gè) q 后跟一個(gè)數(shù)字,則這個(gè)統(tǒng)計(jì)數(shù)據(jù)是特定隊(duì)列的一部分。

使用隊(duì)列號(hào)的示例如: tx_q7_bytes 表示此統(tǒng)計(jì)信息適用于隊(duì)列號(hào)7,并表示該隊(duì)列上傳輸?shù)淖止?jié)數(shù)。

7.5.4.2.API設(shè)計(jì)

xstats API使用name,id和value來(lái)允許執(zhí)行查詢(xún)特定的統(tǒng)計(jì)信息。執(zhí)行查找意味著兩件事情:

  • 快速路徑中的統(tǒng)計(jì)信息不執(zhí)行名稱(chēng)字符串比較
  • 允許僅請(qǐng)求感興趣的統(tǒng)計(jì)信息

API通過(guò)將統(tǒng)計(jì)信息的名稱(chēng)映射到唯一的ID來(lái)確保滿(mǎn)足這些要求,該唯一ID用作快速路徑中的查找Key。API允許應(yīng)用程序請(qǐng)求一個(gè)id值數(shù)組,以便PMD只執(zhí)行所需的計(jì)算。預(yù)期的用法是應(yīng)用程序掃描每個(gè)統(tǒng)計(jì)信息的名稱(chēng),并且如果對(duì)該統(tǒng)計(jì)信息感興趣則緩存該id。在快速路徑上,該整數(shù)可用于檢索id表示的統(tǒng)計(jì)信息的實(shí)際值。

7.5.4.3. API函數(shù)

只輸出了少量的函數(shù),用于檢索統(tǒng)計(jì)信息的數(shù)量以及這些統(tǒng)計(jì)信息的名稱(chēng)、ID和數(shù)值。

  • rte_eth_xstats_get_names_by_id():返回統(tǒng)計(jì)信息的名稱(chēng),當(dāng)給定一個(gè)NULL參數(shù)時(shí),函數(shù)返回可用的統(tǒng)計(jì)數(shù)目。
  • rte_eth_xstats_get_id_by_name():搜索與xstat_name匹配的統(tǒng)計(jì)ID。如果找到,則設(shè)置id值。
  • rte_eth_xstats_get_by_id():根據(jù)配提供的ids數(shù)組,填充一系列uint64_t值。如果ids數(shù)組為NULL,則返回所有可用的統(tǒng)計(jì)信息。

7.5.4.4.API用例

考慮一下,應(yīng)用程序需要查看丟棄的數(shù)據(jù)包數(shù)目。如果沒(méi)有數(shù)據(jù)包被丟棄,由于性能原因,應(yīng)用程序不會(huì)讀取任何其他指標(biāo)。如果數(shù)據(jù)包丟棄,應(yīng)用程序?qū)⒕哂幸唤M特定的統(tǒng)計(jì)信息。這一組統(tǒng)計(jì)信息允許應(yīng)用程序決定下一步執(zhí)行的步驟。以下代碼片段展示了如何使用xstats API來(lái)實(shí)現(xiàn)此目標(biāo)。

第一步就是獲取所有統(tǒng)計(jì)信息的名稱(chēng),并列出來(lái)。

struct rte_eth_xstat_name *xstats_names;
uint64_t *values;
int len, i;

/* Get number of stats */
len = rte_eth_xstats_get_names_by_id(port_id, NULL, NULL, 0);
if (len < 0) {
    printf("Cannot get xstats count\n");
    goto err;
}

xstats_names = malloc(sizeof(struct rte_eth_xstat_name) * len);
if (xstats_names == NULL) {
    printf("Cannot allocate memory for xstat names\n");
    goto err;
}

/* Retrieve xstats names, passing NULL for IDs to return all statistics */
if (len != rte_eth_xstats_get_names_by_id(port_id, xstats_names, NULL, len)) {
    printf("Cannot get xstat names\n");
    goto err;
}

values = malloc(sizeof(values) * len);
if (values == NULL) {
    printf("Cannot allocate memory for xstats\n");
    goto err;
}

/* Getting xstats values */
if (len != rte_eth_xstats_get_by_id(port_id, NULL, values, len)) {
    printf("Cannot get xstat values\n");
    goto err;
}

/* Print all xstats names and values */
for (i = 0; i < len; i++) {
    printf("%s: %"PRIu64"\n", xstats_names[i].name, values[i]);
}

該應(yīng)用程序可以訪問(wèn)PMD暴露的所有統(tǒng)計(jì)信息的名稱(chēng)。應(yīng)用程序自己決定哪些統(tǒng)計(jì)信息是感興趣的,通過(guò)查找名稱(chēng)來(lái)緩存這些統(tǒng)計(jì)信息的ID。

uint64_t id;
uint64_t value;
const char *xstat_name = "rx_errors";

if(!rte_eth_xstats_get_id_by_name(port_id, xstat_name, &id)) {
    rte_eth_xstats_get_by_id(port_id, &id, &value, 1);
    printf("%s: %"PRIu64"\n", xstat_name, value);
}
else {
    printf("Cannot find xstats with a given name\n");
    goto err;
}

API為應(yīng)用程序提供了靈活性,以便它可以使用包含多個(gè)ID號(hào)的數(shù)組查找多個(gè)統(tǒng)計(jì)信息。這樣可以減少檢索統(tǒng)計(jì)信息的函數(shù)調(diào)用開(kāi)銷(xiāo),并使得應(yīng)用程序更統(tǒng)一查找多個(gè)統(tǒng)計(jì)信息。

#define APP_NUM_STATS 4
/* application cached these ids previously; see above */
uint64_t ids_array[APP_NUM_STATS] = {3,4,7,21};
uint64_t value_array[APP_NUM_STATS];

/* Getting multiple xstats values from array of IDs */
rte_eth_xstats_get_by_id(port_id, ids_array, value_array, APP_NUM_STATS);

uint32_t i;
for(i = 0; i < APP_NUM_STATS; i++) {
    printf("%d: %"PRIu64"\n", ids_array[i], value_array[i]);
}

用于xstats數(shù)組查找的API允許應(yīng)用程序創(chuàng)建多個(gè)統(tǒng)計(jì)信息組,并使用單個(gè)API調(diào)用查找這些ID值。作為最終查找結(jié)果,應(yīng)用程序能夠?qū)崿F(xiàn)監(jiān)視單個(gè)統(tǒng)計(jì)信息(在這種情況下為rx_errors)的目標(biāo),如果顯示數(shù)據(jù)包被丟棄,則可以使用ID數(shù)組輕松地檢索組統(tǒng)計(jì)信息。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容