深入理解linux網路技術之驅動層

2021-06-25 16:47:33 字數 1804 閱讀 9377

最近我又開始看這個《深入理解linux網路技術內幕》了。以前一直覺得這本書是乙個巨無霸,昨天和前天各花了一點時間。大概是一直在搞核心的緣故吧!現在看起來倒不是很吃力了。大概看了1/3吧,雖然的確有點跑馬觀花了意味,但是自我感覺還是明白了主幹的東西。《linux核心情景分析》裡面對軟中斷講得比較簡略,而《深入》那書後邊還圖書館了,所以導致我對軟中斷的理解很不夠透徹。現在大致終結一下吧!

首先,軟中斷的執行是由ksoftirqd完成的,這是多個核心程序,每個cpu都有乙個這樣的程序,申明如下:

declare_per_cpu(struct list_head [nr_softirqs], softirq_work_list);

declare_per_cpu(struct task_struct *, ksoftirqd);

static struct softirq_action softirq_vec[nr_softirqs] __cacheline_aligned_in_smp;

struct softirq_action

;

softirq_action就是乙個函式指標,nr_softirqs就是軟中斷的個數,不信你可以看看下邊。
enum

;

在每個ksoftirqd執行緒中,它所幹的是就去執行softirq_vec函式指標陣列中的函式,相當於按優先順序執行。每個軟中斷的函式都是在核心裡定義好的。比如tasklet_hi_action(), tasklet_action(),net_rx_action()。當然,這還不算完。對於不同的軟中斷函式,執行的方法也不一樣。就tasklet_hi_action()和tasklet_action()而言,它們各自有乙個鍊錶分別叫tasklet_vec,tasklet_hi_vec。這些鍊錶單元結構都是tasklet_struct型別的。定義如下:

struct tasklet_struct

;

static define_per_cpu(struct tasklet_head, tasklet_vec);

static define_per_cpu(struct tasklet_head, tasklet_hi_vec);

看到那個func函式指標沒有,這個就是鍊錶最重要的元素。軟中斷函式tasklet_hi_action()和tasklet_action()的作用就是呼叫這個鍊錶中的func函式。可以根據需要練新增tasklet_struct元素進入鍊錶。對於net_rx_action(),這函式就是真正銜接中斷的函式,算是所謂的「bottom half」了。它的工作機理其實和前面兩個差不多。依然是乙個鍊錶,鍊錶的表頭在softnet_data。這是乙個全域性的資料結構。每乙個cpu都有乙個對應的soft_data,它包含乙個headlist polllist的指標。polllist實際連線了napi_struct型別。而這個napi_struct型別是net_device息息相關。napi_struct中的poll指標就指向了具體的驅動模組中的poll()函式。到這裡,我們終於找到了和上半部銜接的地方了。下面這是e100驅動的poll函式。
static int e100_poll(struct napi_struct *napi, int budget)

return work_done;

}

看似清爽的函式其實並沒有這麼簡單。主要的工作都是e100_rx_clean()在幹。然後就是接收了,值得一提的是e100使用了dma,然後呼叫的netif_receive_skb(skb)。這的確是歷史性的一刻了。這標誌著我們的資料經過千辛萬苦終於是走出了驅動層,向l3邁進。

《深入理解Linux網路技術內幕》閱讀筆記(五)

通過中斷,nic能夠告知其驅動程式幾種不同的事情,包括 1.接收一幀。2.傳輸失敗。3.dma傳輸已成功完成。給定乙個幀傳輸,當幀上載至nic的記憶體準備在此媒介上傳輸時,驅動程式就會將持有該幀的緩衝區釋放掉。使用同步傳輸時 無dma 當該幀已上傳至nic,驅動程式就會立刻知道。但使用dma時,也就...

《深入理解Linux網路技術內幕》閱讀筆記(六)

pci的優點之一是,其支援尋找irq和每個裝置所需的其他資源的探測方式相當優雅。模組可以在載入期間接收一些輸入引數,以告知該如何配置其所負責的所有裝置。但是,有些時候,特別是pci這類匯流排,讓驅動程式自行檢查系統上的裝置,然後為其負責的那些裝置做配置會比較簡單一點。必要時,可以退回到手動配置。探測...

《深入理解Linux網路技術內幕》閱讀筆記(九)

當特定事件發生時,裝置驅動程式會代表核心指示裝置產生硬體中斷。處理函式會把該幀排入佇列某處,然後通知核心。該技術是低流量負載下的最佳選擇。遺憾的是,在高流量負載下就無法良好運作 每接收乙個幀就強制產生中斷,很快就會讓cpu為處理中斷事件浪費所有的時間。負責接收幀的 分成兩部分,首先,驅動程式把該幀拷...