歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux管理 >> Linux網絡 >> Linux網絡內核數據幀的接收過程:數據鏈路層(概念篇)

Linux網絡內核數據幀的接收過程:數據鏈路層(概念篇)

日期:2017/3/1 10:19:40   编辑:Linux網絡

處理鏈路層(L2)的函數是由中斷事件驅動的。硬件會使用中斷事件通知CPU,該幀已經可用了。接收中斷事件的CPU會執行do_IRQ函數。IRQ編號引發正確的中斷處理函數被啟用。此處理函數通常是設備驅動程序在設備驅動程序初始化期間所注冊的函數。IRQ函數處理函數會在中斷模式下執行,即後續的中斷事件都會暫時被關閉。

中斷處理函數會執行一些立即性的任務,然後把其他任務安排到下半部函數中以便在稍後執行,明確地講,中斷處理函數會

1、 把幀拷貝到sk_buff數據結構中。

2、 對一些sk_buff參數做初始化,以便在稍後由上面的網絡層使用(這是通過skb->protocol的字段來表示較高層協議處理函數)

3、 更新其他一些設備私用的參數。

4、 為NET_RX_SOFTIRQ軟IRQ調度以准備執行,借此通知內核新幀的事。

由於設備發出中斷事件的理由各有不同(新幀已接收、幀已成功傳輸等等),內核的代碼會配合中斷通知信息,使得設備驅動程序處理例程可以按類型處理中斷事件

(一)、設備的開啟和關閉

當net_device->status中的__LINK_STATE_START標識被設置時,設備就可被視為已開啟。當設備打開時,這個標識通常會被設置,而當設備關閉時,就會被清除。

(二)、隊列

討論L2行為時,通常會提到幀接收和傳 輸時所需的隊列。每個隊列都有一個指針指向其相關聯的設備,以及一個指針指向存儲輸入/輸出緩沖區的skb_buff數據結構。只有少數專用的設備可以不需要隊列就能工作,其中一例是環回設備,環回設備可以省掉隊列,因為當你從環回設備傳出一個封包時,該封包會立刻被遞送出去,而無需排入隊列的中間過程。再者,因為在環回設備上的傳輸不會失敗,也沒有必要讓封包重新排入隊列以嘗試另一次傳輸。

(三)、NAPI與netif_rx

在Linux2.6版本中,引進了一套新的API以處理入口幀,由於找不到更好的名稱,所以稱之為NAPI(New API)。由於還有很多設備沒有更新成NAPI,所以Linux驅動程序通知內核新幀的事有兩種方式。

通過舊函數netif_rx

這種方法只通過中斷期間來處理多幀。

通過NAPI機制

這種方法是通過中斷與輪詢混合使用來處理多幀的。

(1)NAPI簡介

雖然有些NIC的設備驅動程序尚未改用NAIP,但是新型基礎架構已經整合至內核,而且連舊式的netif_rx和內核其余部分之間的接口也都把NAPI考慮進來了。所以這裡先簡單介紹下NAPI的特性才來看netif_rx。

NAPI混合了中斷事件和輪詢,在高流量負載下其性能會比舊方法要好,因為可以大幅減少CPU的負載。

在舊模式中,設備驅動程序會為其所接收的每個幀都產生一個中斷事件。在高流量負載下,花在處理中斷事件的時間會造成資源相當程序的浪費。

NAPI背後的主要想法很簡單:混合使用中斷事件和輪詢,而不使用純粹的中斷事件驅動模型。如果接收到新幀時,內核還沒完成處理前幾個幀的工作,驅動程序就沒必要產生其他中斷事件:讓內核一直處理設備輸入隊列中的數據會比較簡單一點,然後當該隊列為空時再重新開啟中斷功能。如此一來,驅動程序就能獲得中斷事件和輪詢的優點:

◇異步事件,如幀的接收,是由中斷事件指出,如此一來,如果設備的入口隊列是空的,內核就不用一直去檢查了。

◇ 如果內核知道設備的入口隊列中有數據存在,就沒必要浪費時間去處理中斷事件通知信息。用簡單的輪詢就夠了。

(2)NAPI所用之net_device字段

為了處理驅動程序使用NAPI接口的設備,有四個新字段添加到此結構中,以供NET_RX_SOFTIRQ軟IRQ使用。其它設備(非NAPI的設備)不會用到這些字段,但是它們可共享嵌入在softnet_data結構中作為backlog_dev字段的net_device結構的字段。(backlog_dev是積壓設備,主要是為了處理非NAPI的驅動程序來滿足NAPI的架構的一個對象)

poll

這個虛擬函數可用於把緩沖區從設備的輸入隊列中退出。此隊列是使用NAPI設備的私有隊列,而softnet_data->input_pkt_queu供其它設備使用

poll_list

這是設備列表,其中的設備就是在入口隊列中有新幀等待被處理的設備。這些設備就是所謂的處於輪詢狀態。此列表的頭為softnet_data->poll_list。此列表中的設備都處於中斷功能關閉狀態,而內核當前正在予以輪詢。

由於Linux現在已經將NAPI的架構整合進了內核,並取代了老式的架構,所以當不支持NAPI的設備接受到來的新幀時,這個設備列表中的當前設備就是剛才說的積壓設備——backlog_dev。積壓設備有自己的方法來模擬NAPI的機制。這個之後會說明。

quota

weight

quota(配額)是一個整數,代表的是poll虛擬函數一次可以從隊列退出的緩沖區的最大數目。其值的增加以weight為單位,用於在不同設備間施加某種公平性。配額越低, 表示潛在的延時愈低,因此讓其他設備餓死的風險就愈低,另方面,低配額會增加設備間的切換量,因此整體的耗費會增加。

對配有非NAPI驅動程序的設備而言,weight的默認值為64。存儲在net/core/dev.c頂端的weight_p變量。weight_p之值可通過/proc修改。

對配有NAPI程序的設備而言,默認值是由驅動程序所選。最常見的值是64,但是也有使用16和32的,其值可能過sysfs調整。

Copyright © Linux教程網 All Rights Reserved