裝置模組中資料報接收的兩個佇列

2021-08-22 13:33:34 字數 1408 閱讀 1339

驅動層程式通過netif_rx或者netif_rx_ni將接收的資料報傳入到裝置層,裝置模組分成兩個階段處理資料報。第一階段將資料報新增到接收佇列(input_pkt_queue)末尾,接收處理完成;第二階段將接收佇列的資料報移動到處理佇列(process_queue)中。兩個階段的操作都是鍊錶操作,不涉及到skb資料報的拷貝。

在第一階段中,僅是新增到接收佇列即返回,以便驅動程式可以接收下乙個資料報。第二階段在中斷下半部中執行,首先處理process_queue佇列中已有的資料報,之後將第一階段新增到input_pkt_queue佇列中的資料報,拼接到process_queue佇列中,等待下次處理。

網路裝置模組在初始化時,為每乙個cpu初始化接收和處理佇列。

define_per_cpu_aligned(struct softnet_data, softnet_data);

函式enqueue_to_backlog負責將資料報新增到接收佇列中。首先取出對應cpu的input_pkt_queue佇列長度,如果其值已經超過netdev_max_backlog(預設為1000,可通過proc檔案/proc/sys/net/core/netdev_max_backlog修改)的最大值,此資料報skb將會被丟棄。否則新增到接收佇列的末尾。

由於每個cpu具有單獨的input_pkt_queue佇列,在對其操作的時候,我們只需要關閉當前cpu的中斷即可。

static int enqueue_to_backlog(struct sk_buff *skb, int cpu, unsigned int *qtail)

}

核心在下半部中呼叫process_backlog函式處理資料報。由其實現可見,對於process_queue佇列中資料報,呼叫網路核心接收函式__netif_receive_skb處理,知道配額quota用完為止。之後,判讀如果接收佇列input_pkt_queue不為空,將接收佇列拼接到處理佇列上。接收佇列清空。繼續處理新增到process_queue佇列的資料報。

在處理接收佇列input_pkt_queue時,關閉本地cpu的中斷,確保佇列操作的完整性。

static int process_backlog(struct napi_struct *napi, int quota)

local_irq_disable();

if (skb_queue_empty(&sd->input_pkt_queue)) else

local_irq_enable();

}}

由函式process_backlog可見,process_queue處理佇列的存在,使在處理資料報時不必關閉本地cpu的中斷。而對input_pkt_queue佇列的處理又做到了精簡,提高了效率,關閉中斷的時間縮短了。

核心版本

linux-4.15

裝置模組中資料報接收的兩個佇列 CSDN部落格

驅動層程式通過netif rx或者netif rx ni將接收的資料報傳入到裝置層,裝置模組分成兩個階段處理資料報。第一階段將資料報新增到接收佇列 input pkt queue 末尾,接收處理完成 第二階段將接收佇列的資料報移動到處理佇列 process queue 中。兩個階段的操作都是鍊錶操作...

tcp ip stack 中的資料報佇列

tcp ip 是一種儲存 的協議,因此,在 stack 中必然存在資料報的佇列 sk buff queue 正是這些佇列,將 stack 的處理邏輯比較清晰的劃分成幾個部分。資料報接收路徑上的佇列 1 網路層佇列 softnet data this cpu input pkt queue 每個 cp...

Python中的兩個內建模組介紹

使用了python一段時間程式設計客棧後,可以說python的基本單位就是模組了,在使用模組的時候我們一般會使用通過import語句來將其匯入,但是我們在沒有匯入任何模組的時候,我們卻能使用這樣的一些函式 int str len range 以及使用try except語句來捕獲異常,那麼這些又是從...