部落格:blog.focus-linux.net linuxfocus.blog.chinaunix.net
微網誌:weibo.com/glinuxer
QQ技術群:4367710
前幾天聽一個朋友提到這個netmap,看了它的介紹和設計,确實是個好東西。其設計思想與業界不謀而合——因為為了提高性能,幾個性能瓶頸放在那裡,解決方法自然也是類似的。
由于保密性,我是不可能拿公司的設計來和大家讨論和分享的。而netmap的出現,提供了這麼一個好機會。它既實作了一個高性能的網絡I/O架構,代碼量又不算大,非常适合學習和研究。
首先要感謝netmap的作者,創造出了netmap并無私的分享了他的設計和代碼。netmap的文檔寫得很不錯,這裡我簡單說明一下為什麼netmap可以達到高性能。
1. 利用mmap,将網卡驅動的ring記憶體空間映射到使用者空間。這樣使用者态可以直接通路到原始的資料包,避免了核心和使用者态的兩次拷貝;——前兩天我還想寫這麼一個東西呢。
2. 利用預先配置設定的固定大小的buff來儲存資料包。這樣減少了核心原有的動态配置設定;——對于網絡裝置來說,固定大小的記憶體池比buddy要有效的多。之前我跟Bean_lee也提過此事呵。
3. 批量處理資料包。這樣就減少了系統調用;
更具體的内容,大家直接去netmap的官方網站上看吧,寫得很詳細。雖然英文,大家還是耐着性子好好看看,收獲良多。
從上面netmap的簡單介紹中可以看到,netmap不可避免的要修改網卡驅動。不過這個修改量很小。
下面我以e1000.c為例來分析。由于netmap最早是在FreeBSD上實作的,為了在linux達到最小的修改,使用了大量的宏,這給代碼的閱讀帶來了一些困難。
俺不是寫驅動的。。。e1000_probe裡面很多代碼看不明白,但是不影響我們對netmap的分析。通過netmap的patch,知道是在e1000完成一系列硬體初始化以後,并注冊成功,這時調用e1000_netmap_attach
下面是e1000_netmap_attach的代碼
SOFTC_T是一個宏定義,對于e1000,實際上是e1000_adapter,即e1000網卡驅動對應的private data。 下面是struct netmap_adapter的定義
從struct netmap_adapter可以看出,netmap的注釋是相當詳細。是以後面,我不再列出netmap的結構體定義,大家可以自己檢視,免得滿篇全是代碼。————這樣的注釋,有幾個公司能夠做到?
e1000_netmap_attach完成簡單的初始化工作以後,調用netmap_attach執行真正的attach工作。前者是完成與具體驅動相關的attach工作或者說是準備工作,而後者則是真正的attach。
完成了netmap_attach,e1000的probe函數e1000_probe即執行完畢。