多隊列網卡簡介以及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的定義:

 

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

不管怎么樣,你總該有發送的函數調用吧,就是下面圈起來的這個:

 

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

 

參考:

http://www.landley.net/kdocs/ols/2007/ols2007v2-pages-305-310.pdf

http://vger.kernel.org/~davem/davem_nyc09.pdf

http://www.chineselinuxuniversity.net/kerneldocs/networking/API-dev-queue-xmit.html

http://apps.hi.baidu.com/share/detail/36206005

http://lwn.net/Articles/289137/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM