1. 程式人生 > >多佇列網絡卡簡介以及Linux通過網絡卡傳送資料包原始碼解讀

多佇列網絡卡簡介以及Linux通過網絡卡傳送資料包原始碼解讀

摘自:http://blog.csdn.net/yanghua_kobe/article/details/7485254 

首先我們看一下一個主流多佇列網絡卡(E1000)跟多核CPU之間的關係圖:


非多佇列:

linux的網絡卡由結構體net_device表示,一個該結構體對應一個可以排程的資料包傳送佇列。

資料包的實體在核心中以結構體sk_buff(skb),形如:


多佇列:

一個網絡卡可以擁有多個佇列


接下來,看看TX引擎是如何工作的(注:對於傳送和接收資料包有兩個名詞,分別應對TX,RX)


解釋:

函式-dev_queue_xmit():入隊一個buffer以傳輸到網路驅動裝置。

配合該函式的原始碼來解釋上圖的傳輸過程:

步驟一:可以看到如果裝置支援佇列,則資料包入裝置佇列。在入隊操作前後,有加鎖和釋放佇列鎖的過程。


步驟二:調出裝置的qdisc(該物件是佇列的排隊規則)


QDisc(排隊規則)是queueingdiscipline的簡寫,它是理解流量控制(traffic control)的基礎。無論何時,核心如果需要通過某個網路介面傳送資料包,它都需要按照為這個介面配置的qdisc(排隊規則)把資料包加入佇列。然後,核心會盡可能多地從qdisc裡面取出資料包,把它們交給網路介面卡驅動模組。最簡單的QDisc是pfifo它不對進入的資料包做任何的處理,資料包採用先入先出的方式通過佇列。不過,它會儲存網路介面一時無法處理的資料包。

步驟三:重置skb的佇列對映,置為0


步驟四:tx lock->hard_start_xmit

到這裡,我們好像沒有看到tx_lock、hard_start_xmit函式,反而我們在無佇列的裝置分支中看到了這些:


Dev_hard_start_xmit的定義:


很明顯我們應該撥開雲霧看到一些本質,再次回到裝置支援佇列的分支中(這才是我們關心的):

不管怎麼樣,你總該有傳送的函式呼叫吧,就是下面圈起來的這個:


果不其然,這是一個封裝函式:


參考: