封包傳遞一般使用者通常只看到SOCKET API層級。後續就交手給 Linux 作業系統核心與硬體商去進行傳送。圖1.顯示上下層關係,通常應用層需要指定使用的socket是TCP or UDP。而TCP與UDP的使用SOCKET方式也有不同。呼叫完之後,Linux kernel就會進行接手。在封裝上IP層並且透過網路卡傳遞出去。
圖1
大體運作為網卡收到資料透過PCIe把資料寫入記憶體 (透過DMA的方式),寫完之後再透過硬體中斷去呼叫CPU。此時會占用住CPU,當CPU收到要求後,會再去查網路驅動註冊的中斷處理 function。查到後馬上發出軟體中斷。此時釋放CPU占用。負責處理軟體中斷的 Linux kernel - ksoftirqd 執行緒,開始呼叫 poll function,透過 poll function再轉交給各層級的協定去處理 (例如一開始可能是 TCP/IP呼叫,就會丟給TCP/IP的協議軟體處理)。
對應 ksoftirqd 需要確認軟體中斷時要呼叫誰,其中Linux定義了RX_SOFTIRQ 與 TX_SOFTIRQ (細節參考連結)。而TX & RX SOFTIRQ後透過 net_tx_action來看註冊的協議層服務。我們常用的 UDP/ TCP 服務會在 initial 時把 udp/tcp/ip (udp_rcv/ tcp_v4_rcv/ ip_rcv) 等服務載入(細節參考連結)。
RX errors: 表示總的收包的錯誤數量,這包括 too-long-frames 錯誤,Ring Buffer 溢出錯誤,crc 校驗錯誤,幀同步錯誤,fifo overruns 以及 missed pkg 等等。
RX dropped: 表示數據包已經進入了 Ring Buffer,但是由於內存不夠等系統原因,導致在拷貝到內存的過程中被丟棄。
RX overruns: 表示了 fifo 的 overruns,這是由於 Ring Buffer(aka Driver Queue) 傳輸的 IO 大於 kernel 能夠處理的 IO 導致的,而 Ring Buffer 則是指在發起 IRQ 請求之前的那塊 buffer。很明顯,overruns 的增大意味着數據包沒到 Ring Buffer 就被網卡物理層給丟棄了,而 CPU 無法即使的處理中斷是造成 Ring Buffer 滿的原因之一,上面那臺有問題的機器就是因爲 interruprs 分佈的不均勻(都壓在 core0),沒有做 affinity 而造成的丟包。
RX frame: 表示 misaligned 的 frames。
對於 TX 的來說,出現上述 counter 增大的原因主要包括 aborted transmission, errors due to carrirer, fifo error, heartbeat erros 以及 windown error,而 collisions 則表示由於 CSMA/CD 造成的傳輸中斷。
[原文] ifconfig 下面的一些字段(errors, dropped, overruns)