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