網絡收包流程-報文從網卡驅動到網絡層(或者網橋)的流程(非NAPI、NAPI)(一)

1.上圖(網上的沒我這個詳細,哈哈):

2.具體說明NAPI和非NAPI的區別:
(1) 支持NAPI的網卡驅動必須提供輪詢方法poll()。
(2) 非NAPI的內核接口爲netif_rx(),NAPI的內核接口爲napi_schedule()。
(3) 非NAPI使用共享的CPU隊列softnet_data->input_pkt_queue,NAPI使用設備內存(或者設備驅動程序的接收環)。
net_rx函數的作用:
    a.爲skb分配內存
    b.從網卡copy內存到skb空間
netif_rx的作用:
     a.將net_rx從網卡獲取的skb,放到當前cpu的softnet_data公共等待隊列input_pkt_queue,即enqueue_to_backlog-->__skb_queue_tail(&sd->input_pkt_queue, skb);
     b.將process_backlog加入到當前cpu的softnet_data的poll_list中,即enqueue_to_backlog-->____napi_schedule->list_add_tail(&napi->poll_list, &sd->poll_list);
     c.觸發軟中斷,即__raise_softirq_irqoff(NET_RX_SOFTIRQ);
napi_schedule的作用:
     a.將特定於硬件的poll_list加入到當前cpu的softnet_data的poll_list(container_of函數即可通過poll_list獲得對應的napi_struct結構體,從而可以獲得poll函數)
     b.觸發軟中斷,即__raise_softirq_irqoff(NET_RX_SOFTIRQ);
         注意:NAPI方式的skb直接從設備內存獲得,不用自己維護內存
3.中斷方式與NAPI的結合:
             NAPI 的核心在於:在一個繁忙網絡,每次有網絡數據包到達時,不需要都引發中斷,因爲高頻率的中斷可能會影響系統的整體效率,假象一個場景,我們此時使用標準的 100M 網卡,可能實際達到的接收速率爲 80MBits/s,而此時數據包平均長度爲 1500Bytes,則每秒產生的中斷數目爲:
 
                                80M bits/s / (8  * 1500 Byte) = (80 * 1024 * 1024) bit/s / (8  * 1500 Byte) = 6990 箇中斷 /s

           每秒6990箇中斷,對於系統是個很大的壓力,此時其實可以轉爲使用輪詢 (polling) 來處理,而不是中斷;但輪詢在網絡流量較小的時沒有效率,因此低流量時,基於中斷的方式則比較合適,這就是 NAPI 出現的原因,在低流量時候使用中斷接收數據包,而在高流量時候則使用基於輪詢的方式接收。
4.NAPI方式的優勢:NAPI 適合處理高速率數據包的處理,而帶來的好處則是:
     1.中斷緩和 (Interrupt mitigation),由上面的例子可以看到,在高流量下,網卡產生的中斷可能達到每秒幾千次,而如果每次中斷都需要系統來處理,是一個很大的壓力,而 NAPI 使用輪詢時是禁止了網卡的接收中斷的,這樣會減小系統處理中斷的壓力。
     2.數據包節流 (Packet throttling),NAPI 之前的 Linux NIC 驅動總在接收到數據包之後產生一個 IRQ,接着在中斷服務例程裏將這個 skb 加入本地的 softnet_data,然後觸發本地 NET_RX_SOFTIRQ 軟中斷後續處理。如果包速過高,因爲 IRQ 的優先級高於 SoftIRQ,導致系統的大部分資源都在響應中斷,但 softnet 的隊列大小有限,接收到的超額數據包也只能丟掉,所以這時這個模型是在用寶貴的系統資源做無用功。而 NAPI 則在這樣的情況下,直接把包丟掉,不會繼續將需要丟掉的數據包扔給內核去處理,這樣,網卡將需要丟掉的數據包儘可能的早丟棄掉,內核將不可見需要丟掉的數據包,這樣也減少了內核的壓力。

5.NAPI的實現原理:
        
假定某個網絡適配器此前沒有分組到達,但從現在開始,分組將以高頻率頻繁到達。這就是NAPI設備的情況,如下所述。
(1) 第一個分組將導致網絡適配器發出IRQ。爲防止進一步的分組導致發出更多的IRQ,驅動程序會在硬中斷處理流程中關閉該適配器的Rx IRQ。並將該適配器放置到一個輪詢表上。
(2) 只要適配器上還有分組需要處理,內核就一直對輪詢表上的設備進行輪詢。
(3) 重新啓用Rx中斷。
        如果在新的分組到達時,舊的分組仍然處於處理過程中,工作不會因額外的中斷而減速。雖然對設備驅動程序(和一般意義上的內核代碼)來說輪詢通常是一個很差的方法,但在這裏該方法沒有什麼不利之處:在沒有分組還需要處理時,將停止輪詢,設備將回復到通常的IRQ驅動的運行方式。在沒有中斷支持的情況下,輪詢空的接收隊列將不必要地浪費時間,但NAPI並非如此。
        NAPI的另一個優點是可以高效地丟棄分組。如果內核確信因爲有很多其他工作需要處理,而導致無法處理任何新的分組,那麼網絡適配器可以直接丟棄分組,無須複製到內核。
只有設備滿足如下兩個條件時,才能實現NAPI方法。
(1) 設備必須能夠保留多個接收的分組,例如保存到DMA環形緩衝區中。下文將該緩衝區稱爲Rx緩衝區。
(2) 該設備必須能夠禁用用於分組接收的IRQ。而且,發送分組或其他可能通過IRQ進行的操作,都仍然必須是啓用的。
       如果系統中有多個設備,會怎麼樣呢?這是通過循環輪詢各個設備來解決的。


6.具體網卡的舉例說明:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章