DPDK 報文收發流程(二十五)

2021-10-06 15:31:53 字數 3243 閱讀 9888

傳統方式接收報文時,當網絡卡接收到報文後會產生硬體中斷,進而報文會通過協議棧,最後到達應用層,這個過程需要核心協議棧的處理。 和傳統報文接收不同,當應用層想要接收來自網絡卡的報文時, 應用層通過while死迴圈的方式,呼叫rte_eth_rx_burst介面輪詢接收來自網絡卡的報文,相當於繞過了核心協議棧,將核心旁路了。通過輪詢的方式,報文不經過核心,提高了網路**效能,同時也降低了核心與使用者態系統呼叫的開銷。

來看下報文接收的整體流程。當網絡卡接收到報文時將會產生硬體中斷,通知dma控制器接收報文。dma控制器會從網絡卡接收佇列中將報文拷貝到硬體接收空間(也就是描述符空間)指向的位址位置,也就是mbuf。最終dma控制器將報文從網絡卡接收佇列中拷貝到mbuf來。 應用層通過while死迴圈,輪詢呼叫rte_eth_rx_burst介面,從這個mbuf軟體接收空間中獲取報文。

現在來看下eth_igb_recv_pkts介面的實現過程。

首先根據應用層最後一次獲取報文的位置,進而從描述符佇列找到待被應用層接收的描述符。此時會判斷描述符中的status_error是否已經打上了dd標記,有dd標記說明dma控制器已經把報文放到mbuf中了。這裡解釋下dd標記,當dma控制器將接收到的報文儲存到描述符指向的mbuf空間時,由dma控制器打上dd標記,表示dma控制器已經把報文放到mbuf中了。應用層在獲取完報文後,需要清除dd標記。

找到了描述符的位置,也就找到了mbuf空間。此時會根據描述符裡面儲存的資訊,填充mbuf結構。例如填充報文的長度,vlanid, rss等資訊。填充完mbuf後,將這個mbuf儲存到應用層傳進來的結構中,返回給應用層,這樣應用層就獲取到了這個報文。

uint16_t eth_igb_recv_pkts

(void

*rx_queue,

struct rte_mbuf *

*rx_pkts, uint16_t nb_pkts)

;//找到了描述符的位置,也就從軟體佇列中找到了mbuf

rxe =

&sw_ring[rx_id]

; rx_id++

; rxm = rxe->mbuf;

//填充mbuf

pkt_len =

(uint16_t)

(rte_le_to_cpu_16

(rxd.wb.upper.length)

- rxq->crc_len)

; rxm->data_off = rte_pktmbuf_headroom;

rxm->nb_segs =1;

rxm->pkt_len = pkt_len;

rxm->data_len = pkt_len;

rxm->port = rxq->port_id;

rxm->hash.rss = rxd.wb.lower.hi_dword.rss;

rxm->vlan_tci =

rte_le_to_cpu_16

(rxd.wb.upper.vlan)

;//儲存到應用層

rx_pkts[nb_rx++

]= rxm;

}}

需要注意的是,將mbuf的位址儲存到描述符中,此時會將dd標記給清0,這樣dma控制器就認為這個mbuf裡面的內容已經被應用層接收了,收到新報文後可以重新放到這個mbuf中。

uint16_t eth_igb_recv_pkts

(void

*rx_queue,

struct rte_mbuf *

*rx_pkts, uint16_t nb_pkts)

}

先整體來看下報文的傳送流程。當應用層需要傳送報文時,呼叫rte_eth_tx_burst介面,將報文放到軟體傳送空間,也就是mbuf空間中。同時將mbuf的位址寫入到硬體傳送空間,也就是描述符空間。dma控制器讀取描述符空間,就知道需要從描述符指向的位置,也就是mbuf中獲取報文,然後通過網絡卡傳送出去。

來看下**的實現過程。應用層呼叫rte_eth_tx_burst介面來傳送報文,函式內部會呼叫pmd使用者態驅動的傳送報文介面。如果是e1000網絡卡,則pmd使用者態驅動傳送報文的介面為eth_igb_xmit_pkts

//傳送報文

uint16_t rte_eth_tx_burst

(uint8_t port_id, uint16_t queue_id,

struct rte_mbuf *

*tx_pkts, uint16_t nb_pkts)

當應用層要發包時,eth_igb_xmit_pkts內部會將應用層的報文放到軟體佇列中。在軟體佇列中找到了最後一次傳送的的位置後,就可以將報文放到這個軟體佇列相應位置上。應用層要傳送的報文有可能是需要分片的,每乙個分片報文都會占用軟體佇列中的乙個元素。某個報文的所有分片報文所占用的軟體佇列元素,last_id都指向同乙個軟體佇列元素。

}需要注意的是,這個傳送過程,也是將mbuf、dma控制器、描述符佇列關聯起來的過程。

uint16_t eth_igb_xmit_pkts

(void

*tx_queue,

struct rte_mbuf *

*tx_pkts, uint16_t nb_pkts)

while

(m_seg !=

null);

}

到此為止,dpdk報文的傳送,接收流程已經分析完成

演算法(二十五)

1 給定兩個不字串,求出最長公共子串行的長度。int longestpublicsubsequence string x,string y else return math.max longestpublicsubsequence x.substring 1 y.substring 0 longes...

Effective C 之二十五

要點 提供不會丟擲異常的swap函式。swap自stl引入後就成為異常安全 exception safe 程式設計的基石。在條款11避免自賦值時已談到過。stl中swap的預設實現是通過臨時變數實現交換。但是對某些型別這是很低效的,例如pimpl只需要交換指標即可。之後,meyers提出在std命名...

Linux基礎(二十五)

進入linux字元介面方式有字元介面 圖形介面下的終端以及虛擬控制台等方式。在字元介面下,虛擬控制台的選擇可以通過按下 alt 鍵和1個功能鍵來實現,功能鍵通常為f1 f6鍵。比如使用者登入後,按下 alt f2 鍵,使用者可以看 login 提示符,說明使用者進入了第2個虛擬控制台。然後只需利用按...