Linux內核的netpoll框架與netconsole

雖然和網絡相關,可是它卻不是網絡協議棧的一部分,這就是netpoll。
它只是一個出入口的處理框架。所謂的網絡,它的終端節點就是主機,數據從主機的網卡發出,通過一個出口處理過程,網卡接收到一個數據包,通過一個入口處理過程,這一出一入的過程處理分爲兩種方式:
api

1.中斷的方式

出口處理過程-數據排入發送隊列,讀取特定寄存器值,待網卡狀態適合發送式,發送,等待發送後的中斷通知,繼續。
入口處理過程-數據被網卡收到,網卡中斷CPU,CPU進而處理數據接收的過程。
網絡協議棧下接的就是這種中斷的出入口處理方式。
緩存

2.poll的方式

出口處理過程-數據排入發送隊列,讀取特定寄存器值,待網卡狀態適合發送式,發送,不等待發送後的中斷通知,繼續讀取寄存器以及根據隊列狀況權衡是否適合發送。
入口處理過程-數據被網卡收到,等待poll邏輯在適當的時候去主動poll網卡,如有數據,則將其從特定的網卡緩存讀出。
Linux netpoll就是利用的這種方式。這種方式徹底不依賴中斷。
事實老是比提及來更麻煩。
要講清楚這個有點混亂的主題,不得不引入第三種出入口處理方式,那就是中斷和poll結合的方式,這就是NAPI方式。我把三種方式的圖示先給出:
a.中斷方式
網絡


wKiom1VYM2DAJj_wAACoYryGKf4901.jpg


b.poll方式
框架


wKioL1VYNOzCOTAzAACjX16Npf0569.jpg


c.NAPI方式
ide


wKiom1VYM4KwSRZsAACrP0fRVwQ275.jpg


理 解了這個,剩下的就都理解了。至於爲什麼會有NAPI,在本文中只能簡單說一句:在高速高帶寬網絡中,數據包持續到來,每個包中斷一次CPU的話,CPU 有點吃不消,反而耽誤了CPU處理這些數據包,若是以前的數據包尚未處理完,最好的辦法就是將數據包排入一個隊列,而後沉默,不要打擾CPU,等CPU 空下來的時候,本身去poll這些隊列裏面的數據包,這就是NAPI。
       純中斷的方式咱們都很熟悉,也是最直接的方式。然而爲什麼要有純poll的方式呢?使用純poll的場合在中斷徹底不起做用的狀況下。舉一個例子,系統 panic以後。此時中斷控制器將可能被disable掉,不管如何,此時的機器已經和外界失聯了,然而若是此時必須須要一個方式對外界通告本身的死因的 話,這種netpoll的方式就派上用場了,由於它是純手工的,徹底不依賴系統的中斷機制。另一種場合比panic好一些,那就是協議棧故障,若是使用 中斷或者NAPI的方式,因爲它上接的就是協議棧,netif_receive_skb中又沒有什麼HOOK點,此時使用netpoll能夠改變數據包的 處理路徑,經過一個agent能夠實現遠程debug。
       不要把中斷想象的太神祕。它無非也就是一個通知機制,告訴CPU,如今請查詢個人狀態,該幹啥就幹啥。事實上,當CPU收到網卡中斷的時候,它也不知道該 幹啥,它只會調用中斷處理函數,其內部會去讀取一寫寄存器的狀態,而後才能知道如今該幹什麼,好比能夠發送數據包,好比收到一個數據包等。既然如此,即便 在關中斷的情形下,若是不依靠中斷,CPU擇機主動調用一下網卡的中斷處理函數,讀取一寫寄存器的狀態,是否是也能知道該幹什麼呢?答案固然是確定的了! 這就是netpoll的邏輯,它使用兩步完成任務:
1.主動調用網卡的中斷處理函數,獲取當前該發送數據包仍是接收到一個數據包;
2.直接hard_xmit數據包或者使用NAPI的接口去poll網卡的數據。
Linux netpoll的整體圖示以下:
函數


wKioL1VYNRugt1bIAANRkrM2NFw394.jpg


這 個圖示中附帶了netconsole的原理,沒想到他是如此的簡單。我記得我曾經寫過一個模塊,將panic後的信息發到遠端,這個是受到了一個 xtables-addons模塊的啓發,起初失敗了,可是最後我仔細debug了內核代碼後,成功了。在成功的過程當中,發現了不少之前不知道的東西。但 是如今看看netconsole吧,它什麼複雜的東西都不須要,只須要兩步:
1.註冊一個console,此後內核buffer的信息就會發到這個console;
2.該console下接netpoll的netpoll_send_skb,此後由netpoll邏輯來處理。
即使在panic後,中斷已經被關了,甚至中斷控制器都關閉的狀況下,只要網卡沒有進水,數據依然能夠收發,它徹底不依賴中斷和協議棧。這簡直太棒了!關於netconsole,我寫多少都不如內核的Document來的好:$kernel/Documentation/networking/netconsole.txt.
       netpoll是Linux內核中的一種在協議棧不可用或者中斷機制異常的狀況下與外界通信的手段,固然它也是一種繞開協議棧的方法。這個位置足夠底層, 寫出來的東西也確定比基於Netfilter的更好玩。Netfilter是在協議棧的特殊點捕獲數據包的,而netpoll卻能夠在網卡之上直接捕獲數 據包,它們甚至連協議棧的最底端都到不了。之後,若是想在內核態直接發包,不再用PACKET套接字從用戶態開始了,構造一個數據包,直接經過 netpoll接口發出。問題是,它採用手工觸發中斷處理函數的方式,效率如何待測試。所以這種機制最好仍是限制於調試和少許內核審計信息的發送吧。用它 作×××,我以爲懸...
測試

相關文章
相關標籤/搜索