網路子系統在鏈路層的收發過程剖析(四)

2021-06-06 05:46:33 字數 1847 閱讀 8652

5),資料報的傳送

資料報的傳送為接收的反過程,傳送過程較之接收過程的複雜性在於它有乙個流量控制層(trafficing control layer),用於實現qos,但不是本文關注的目標。

(1),__netif_schedule ()

當核心有資料報等待傳送時,它會間接呼叫__netif_schedule ()去處理這些資料報:

void __netif_schedule(struct net_device *dev)

} 這個函式的功能很簡單,就是將要有資料要傳送的裝置加softnet_data的output_queue佇列的頭部,這裡要注意,乙個裝置加入是有條件的,如果乙個裝置的狀態為__link_state_sched時,表示這個裝置已經被scheduled,就不必要再一次執行這個函式了。然後這個函式觸發軟中斷,由軟中斷去執行net_tx_action()。

(2),net_tx_action()

這個函式的功能有兩個,其一是釋放softirq_action中完成佇列completion_queue中的skb。

我們知道,當系統執行在中斷上下文中,它應該執行的時間應該越短越好,但如果我們需要在中斷上下文中釋放skb,這就需要比較長的時間了,所以在個時間段裡處理核心的釋放並不是乙個好的選擇。所以,網路子系統在softirq_action結構中設定了乙個完成佇列completion_queue,當核心要在中斷上下文中釋放skb時,它將調dev_kfree_skb_irq(skb):

static inline void dev_kfree_skb_irq(struct sk_buff *skb)

} 可以看到,它並沒有真正的釋放skb空間,而只是將它鏈入完成佇列completion_queue中,並觸發軟中斷,由軟中斷來執行真正的釋放操作,這就是上面提到的net_tx_action()來完成的,這是它的任務之一:

clist = sd->completion_queue;

sd->completion_queue = null;

local_irq_enable();

while (clist)

net_tx_action()的另乙個任務,也是根本的任務,當然是傳送資料報了:

if (sd->output_queue) else }

} 正常情況下,它會將output_queue佇列中的有待傳送的佇列中的裝置遍歷一次,並對各個裝置呼叫qdisc_run(dev)傳送資料報。在這裡,qdisc_run(dev)是屬於qos的內容了。這裡我們只需要知道,qdisc_run(dev)會選擇「合適」的skb然後傳遞給dev_hard_start_xmit(skb, dev)。

(3),dev_hard_start_xmit(skb, dev)

這也只是乙個包裝函式,它首先看有沒有註冊的sniffer,要是存在的話(netdev_nit不等於0),便將乙個副本通過dev_queue_xmit_nit(skb, dev)傳送給它:

if (likely(!skb->next)) {

if (netdev_nit)

dev_queue_xmit_nit(skb, dev);

再之後,就是呼叫驅動程式的hard_start_xmit完成最後的傳送工作了:

return dev->hard_start_xmit(skb, dev);

hard_start_xmit()只要是跟硬體打交道,一般是通知dma完成資料的傳送工作。這裡還有乙個問題是,如果驅動或是硬體本身不支援scatter/gather io,在上面傳送過來的資料又是存在分片的(fragments,即skb_shinfo(skb)->nr_frags不等於0),它只能通過skb_linearize(skb)將原來的skb重新組裝成乙個沒有分片的skb再進行dma。

Linux網路子系統中鏈路層中GRO的處理

根據上篇博文的介紹,gro需要支援gro的每種協議都要實現自己的報文匹配合併函式和合併完成函式。這裡我們先來看看鏈路層上 實現的自己的gro函式。鏈路層的接收匹配函式 napi gro receive napi,skb 該函式對報文進行匹配,並不合併報文。匹配規則 必須同時滿足以下兩個條件 1 兩個...

Linux 網路子系統底層機制分析 1

linux 網路子系統底層機制分析 1 網路子系統在linux中的地位非常重要。在如今這個嚴重依賴網際網路,強調協同工作的時代,乙個高效,穩定的網路處理系統是留住使用者群的基本手段。前段時間花了一部分時間學習了一下linux的網路子系統的源 以及一些處理機制。這部分是由於工作的原因,另一部分原因是想...

Linux網路子系統中報文的接收及NAPI的實現

報文的接收是整個協議棧的入口,負責從網絡卡中把報文接收並送往核心協議棧相應協議處理模組處理。一種是網絡卡產生中斷,通知核心進行接收報文。一次中斷接收乙個報文。在中斷處理程式中把報文從硬體快取中拷貝到記憶體中,並把報文加入到協議棧中對應的入口佇列中,中斷退出時呼叫收包軟中斷來從相應佇列來讀取報文進行處...