0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

linux網(wǎng)絡(luò)棧監(jiān)控及調(diào)優(yōu):數(shù)據(jù)接收

Linux閱碼場 ? 來源:窗有老梅 ? 2023-03-25 16:44 ? 次閱讀

4. 初始化

b5041890-cae8-11ed-bfe3-dac502259ad0.jpg

圖 1 網(wǎng)絡(luò)設(shè)備在 packet 到達(dá)并需要處理時(shí),通常會(huì)觸發(fā)一個(gè) IRQ。IRQ 處理函數(shù)是在很高的優(yōu)先級(jí)下執(zhí)行的,一般會(huì)阻塞其他 IRQs 的觸發(fā)(譯者注:often blocks additional IRQs from being generated。個(gè)人覺得原文這里并不準(zhǔn)確,中斷上下文中關(guān)中往往只是讓 CPU 不響應(yīng)中斷,而不是讓其他設(shè)備直接不發(fā)出中斷)。故而,設(shè)備驅(qū)動(dòng)中的 IRQ 處理函數(shù)必須越快越好,并將比較耗時(shí)的工作挪到中斷上下文之外去執(zhí)行,這就是為啥會(huì)有軟中斷系統(tǒng)。

linux 內(nèi)核軟中斷系統(tǒng)支持在設(shè)備驅(qū)動(dòng)的中斷上下文之外處理工作。網(wǎng)絡(luò)設(shè)備場景下,軟中斷系統(tǒng)用作處理 incoming packets。內(nèi)核在 boot 階段做軟中斷系統(tǒng)的初始化。 圖 1 對(duì)應(yīng)前文“軟中斷”一節(jié),展示的是軟中斷系統(tǒng)及其 per-CPU 內(nèi)核線程的初始化。 軟中斷系統(tǒng)的初始化流程如下:

spawn_ksoftirqd(kernel/softirq.c)調(diào)用 smpboot_register_percpu_thread(kernel/smpboot.c)創(chuàng)建軟中斷內(nèi)核線程(每個(gè) CPU 一個(gè))。如代碼所示,run_ksoftirqd 作為 smp_hotplug_thread 的 thread_fn,會(huì)在一個(gè) loop 中被執(zhí)行。

ksoftirqd 線程會(huì)在 run_ksoftirqd 中運(yùn)行其 processing loop。

隨后,創(chuàng)建 softnet_data 數(shù)據(jù)結(jié)構(gòu)(前文“struct softnet_data 數(shù)據(jù)結(jié)構(gòu)初始化”一節(jié)),每個(gè) CPU 一個(gè)。此數(shù)據(jù)結(jié)構(gòu)包含在網(wǎng)絡(luò)數(shù)據(jù)處理時(shí)所需要的重要信息。另外還有一個(gè) poll_list,下文會(huì)說。設(shè)備驅(qū)動(dòng)調(diào)用 napi_schedule 或其他 NAPI APIs,將 NAPI poll 數(shù)據(jù)結(jié)構(gòu)添加至 poll_list 上。

net_dev_init 調(diào)用 open_softirq 向軟中斷系統(tǒng)注冊 NET_RX_SOFTIRQ 軟中斷,被注冊的軟中斷處理函數(shù)是 net_rx_action(前文“軟中斷處理函數(shù)初始化”一節(jié))。軟中斷內(nèi)核線程會(huì)調(diào)用此函數(shù)來處理 packets。

圖 1 中的第 5 - 8 步與數(shù)據(jù)的到達(dá)有關(guān),下一節(jié)會(huì)說。

5. 數(shù)據(jù)到達(dá)

b536fc38-cae8-11ed-bfe3-dac502259ad0.jpg

圖 2 數(shù)據(jù)從網(wǎng)絡(luò)上來了(前文“數(shù)據(jù)到達(dá)”一節(jié))! 網(wǎng)絡(luò)數(shù)據(jù)到達(dá) NIC 時(shí),NIC 會(huì)通過 DMA 將 packet 數(shù)據(jù)寫入 RAM。igb 網(wǎng)絡(luò)驅(qū)動(dòng)會(huì)在 RAM 中構(gòu)建一個(gè) ring buffer,其指向接收到的 packets。值得注意的是,有些 NIC 支持 "multiqueue",這些 NIC 可以使用多個(gè)處理器來處理 incoming 網(wǎng)絡(luò)數(shù)據(jù)(前文“準(zhǔn)備從網(wǎng)絡(luò)接收數(shù)據(jù)”一節(jié))。

簡化起見,圖 2 只畫了一個(gè) ring buffer,但取決于 NIC 以及硬件配置,你的系統(tǒng)可能使用的是多個(gè)隊(duì)列。 下面流程的細(xì)節(jié)參閱前文“數(shù)據(jù)到達(dá)”一節(jié)。 我們來過一遍數(shù)據(jù)接收流程:

數(shù)據(jù)從網(wǎng)絡(luò)到達(dá) NIC。

NIC 通過 DMA 將網(wǎng)絡(luò)數(shù)據(jù)寫入 RAM。

NIC 觸發(fā)一個(gè) IRQ。

執(zhí)行設(shè)備驅(qū)動(dòng)注冊的 IRQ 處理函數(shù)(前文“中斷處理”一節(jié))。

NIC 清除 IRQ,這樣新 packet 到來時(shí)可以繼續(xù)觸發(fā) IRQs。

調(diào)用 napi_schedule 拉起 NAPI 軟中斷 poll loop(前文“NAPI 與 napi_schedule”一節(jié))。

napi_schedule 的調(diào)用觸發(fā)了 圖 1 中的 5 - 8 步。如后面所見,NAPI 軟中斷 poll loop 拉起的原理,就是翻轉(zhuǎn)一個(gè) bit 域,并向 poll_list 上添加一個(gè)數(shù)據(jù)結(jié)構(gòu)。napi_schedule 沒干什么其他事,這就是驅(qū)動(dòng)將處理工作轉(zhuǎn)交給軟中斷系統(tǒng)的原理。

繼續(xù)分析 圖 1,對(duì)照圖中相應(yīng)的數(shù)字:

驅(qū)動(dòng)調(diào)用 napi_schedule 將驅(qū)動(dòng)的 NAPI poll 數(shù)據(jù)結(jié)構(gòu)添加至當(dāng)前 CPU 的 poll_list 上。

軟中斷 pending bit 會(huì)被置上,如此該 CPU 上的 ksoftirqd 線程知曉有 packets 需要處理。

執(zhí)行 run_ksoftirqd 函數(shù)(在 ksoftirqd 內(nèi)核線程的 loop 中執(zhí)行)。

調(diào)用 __do_softirq 檢查是否有 pending 的 bit 域,以此確認(rèn)是否有 pending 的軟中斷,進(jìn)而調(diào)用 pending 軟中斷的處理函數(shù):net_rx_action,該函數(shù)干了所有的 incoming 網(wǎng)絡(luò)數(shù)據(jù)處理的臟活。

需要注意的是,軟中斷內(nèi)核線程執(zhí)行的是 net_rx_action,而不是設(shè)備驅(qū)動(dòng)的 IRQ 處理函數(shù)。

6. 網(wǎng)絡(luò)數(shù)據(jù)處理的開始

b556db02-cae8-11ed-bfe3-dac502259ad0.jpg

圖 3 至此開始數(shù)據(jù)的處理。net_rx_action 函數(shù)(在 ksoftirqd 內(nèi)核線程中調(diào)用)會(huì)執(zhí)行當(dāng)前 CPU poll_list 上注冊的 NAPI poll 數(shù)據(jù)結(jié)構(gòu)。poll 數(shù)據(jù)結(jié)構(gòu)的注冊一般有兩種情況:

設(shè)備驅(qū)動(dòng)調(diào)用 napi_schedule。

Receive Packet Steering 場景(前文“Receive Packet Steering(RPS)”一節(jié))下使用 Inter-processor Interrupt。

我們將從 poll_list 獲取驅(qū)動(dòng) NAPI 數(shù)據(jù)結(jié)構(gòu)的流程串起來(下一節(jié)會(huì)講 RPS 是怎么通過 IPIs 注冊 NAPI 數(shù)據(jù)結(jié)構(gòu)的)。 圖 3 流程在前文有詳細(xì)拆解過,總結(jié)一下就是:

net_rx_action poll 檢查 NAPI poll list 中的 NAPI 數(shù)據(jù)結(jié)構(gòu)。

校驗(yàn) budget 及消耗的時(shí)間,以確保軟中斷不會(huì)霸占 CPU。

調(diào)用注冊的 poll 函數(shù)(前文“NAPI poll 函數(shù)及權(quán)重”一節(jié))。本文場景下,igb 驅(qū)動(dòng)注冊的是 igb_poll 函數(shù)。

驅(qū)動(dòng)的 poll 函數(shù)收取 RAM ring buffer 中的 packets(前文“NAPI poll”一節(jié))。

packets 進(jìn)一步給到 napi_gro_receive,其可能會(huì)進(jìn)一步被 Generic Receive Offloading 處理(前文“Generic Receive Offloading(GRO)”一節(jié))。

packets 要么被 GRO 處理,這樣整個(gè)調(diào)用鏈也就結(jié)束了;要么 packets 通過 net_receive_skb 進(jìn)一步給到上層協(xié)議棧。

下面會(huì)講 net_receive_skb 是怎么實(shí)現(xiàn) Receive Packet Steering,也就是在多個(gè) CPUs 之間分發(fā) packet 的。

7. 網(wǎng)絡(luò)數(shù)據(jù)的進(jìn)一步處理

b55fbea2-cae8-11ed-bfe3-dac502259ad0.jpg

圖 4 從 netif_receive_skb 開始繼續(xù)網(wǎng)絡(luò)數(shù)據(jù)的處理,數(shù)據(jù)的具體路徑取決于是否使能了 Receive Packet Steering(RPS)。一個(gè)“開箱即用”的 linux 內(nèi)核(譯者注:意思就是通用的發(fā)行版)默認(rèn)是不使能 RPS 的,如果你想用 RPS,就必須顯式地配置及使能之。

RPS 禁能的情況下(前文“禁能 RPS 場景(默認(rèn)配置)”一節(jié)),對(duì)應(yīng) 圖 4 中的如下數(shù)字:

1. netif_receive_skb 將數(shù)據(jù)給到 __netif_receive_core。

6. __netif_receive_core 將數(shù)據(jù)給到系統(tǒng)中可能存在的 taps(前文“packet tap 投遞”一節(jié))(比如 PCAP,https://www.tcpdump.org/manpages/pcap.3pcap.html)。

7. __netif_receive_core 將數(shù)據(jù)給到協(xié)議層注冊的 handlers(前文“協(xié)議層投遞”一節(jié))。大多數(shù)情況下,此 handler 是 IPv4 協(xié)議棧所注冊的 ip_rcv 函數(shù)。

RPS 使能的情況下(前文“使能 RPS 場景”一節(jié)):

netif_receive_skb 將數(shù)據(jù)給到 enqueue_to_backlog。

packets 會(huì)被送到 per-CPU 的輸入隊(duì)列上以待后續(xù)處理。

將遠(yuǎn)端 CPU 的 NAPI 數(shù)據(jù)結(jié)構(gòu)添加至該遠(yuǎn)端 CPU 的 poll_list 上,并向該 CPU 發(fā)一個(gè) IPI,進(jìn)而喚醒遠(yuǎn)端 CPU 上的軟中斷內(nèi)核線程(如果其并未在運(yùn)行的話)。

當(dāng)遠(yuǎn)端 CPU 上的 ksoftirqd 內(nèi)核線程運(yùn)行起來后,其處理模式與上一節(jié)中的相同,不同之處是,注冊進(jìn)來的 poll 函數(shù)是 process_backlog,該函數(shù)會(huì)從當(dāng)前(譯者注:本 CPU) CPU 的輸入隊(duì)列收取 packets。

packets 進(jìn)一步給到 __net_receive_skb_core。

__net_receive_skb_core 將數(shù)據(jù)給到系統(tǒng)中可能存在的 taps(前文“packet tap 投遞”一節(jié))(比如 PCAP)。

__net_receive_skb_core 將數(shù)據(jù)給到協(xié)議層注冊的 handlers(前文“協(xié)議層投遞”一節(jié))。大多數(shù)情況下,此 handler 是 IPv4 協(xié)議棧所注冊的 ip_rcv 函數(shù)。

8. 協(xié)議棧及用戶 sockets

數(shù)據(jù)接下來要走的路徑是:協(xié)議棧、netfilter、Berkeley Packet Filters,最終到達(dá)用戶 socket。 雖然代碼路徑挺長的,但是邏輯是直白清晰的。 網(wǎng)絡(luò)數(shù)據(jù)路徑更詳細(xì)地拆解見前文“協(xié)議層注冊”一節(jié)。下面是 high level 的簡要總結(jié):

IPv4 協(xié)議層通過 ip_rcv 收取 packets。

會(huì)做 netfilter 以及路由優(yōu)化。

目標(biāo)是本機(jī)的數(shù)據(jù),會(huì)進(jìn)一步給到更 high level 的協(xié)議層,比如 UDP。

UDP 協(xié)議層通過 udp_rcv 收取 packets,并通過 udp_queue_rcv_skb 及 sock_queue_rcv 將數(shù)據(jù)入隊(duì)到用戶 socket 的接收 buffer 中。在入隊(duì)到接收 buffer 之前,會(huì)做 Berkeley Packet Filters。

值得注意的是,netfilter 在這個(gè)過程中會(huì)被調(diào)用多次,具體位置參考前文的詳細(xì)拆解(前文“協(xié)議層注冊”一節(jié))。

9. 總結(jié)

linux 網(wǎng)絡(luò)棧極其復(fù)雜,涉及到的系統(tǒng)很多。如果要監(jiān)控這個(gè)復(fù)雜的系統(tǒng)就必須得搞清楚這些系統(tǒng)之間是怎么交互的,以及對(duì)某一系統(tǒng)配置的調(diào)整,會(huì)如何影響到其他系統(tǒng)。本文作為前文的補(bǔ)充,試圖把這些問題梳理的更清晰易懂一些。





審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • cpu
    cpu
    +關(guān)注

    關(guān)注

    68

    文章

    10772

    瀏覽量

    210453
  • Linux系統(tǒng)
    +關(guān)注

    關(guān)注

    4

    文章

    588

    瀏覽量

    27266
  • IRQ
    IRQ
    +關(guān)注

    關(guān)注

    0

    文章

    16

    瀏覽量

    10735
  • 中斷系統(tǒng)
    +關(guān)注

    關(guān)注

    1

    文章

    96

    瀏覽量

    60988

原文標(biāo)題:圖解之 linux 網(wǎng)絡(luò)棧監(jiān)控及調(diào)優(yōu):數(shù)據(jù)接收

文章出處:【微信號(hào):LinuxDev,微信公眾號(hào):Linux閱碼場】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    深度解析Linux網(wǎng)絡(luò)路徑及sk_buff struct 數(shù)據(jù)結(jié)構(gòu)

    的 Segmentation Offloading 技術(shù)(接收端) 1. Linux 網(wǎng)絡(luò)路徑 1.1 發(fā)送端 1.1.1 應(yīng)用層 (1) Socket 應(yīng)用層的各種網(wǎng)絡(luò)應(yīng)用程序基本上
    的頭像 發(fā)表于 10-22 15:04 ?5514次閱讀
    深度解析<b class='flag-5'>Linux</b><b class='flag-5'>網(wǎng)絡(luò)</b>路徑及sk_buff struct <b class='flag-5'>數(shù)據(jù)</b>結(jié)構(gòu)

    Linux網(wǎng)絡(luò)原理與實(shí)現(xiàn)

    本文嘗試從技術(shù)研發(fā)與工程實(shí)踐(而非純理論學(xué)習(xí))角度,在原理與實(shí)現(xiàn)、監(jiān)控告警、 配置調(diào)優(yōu)三方面介紹內(nèi)核5.10 網(wǎng)絡(luò)。由于內(nèi)容非常多,因此分
    發(fā)表于 08-10 08:58 ?3666次閱讀

    基于全HDD aarch64服務(wù)器的Ceph性能調(diào)優(yōu)實(shí)踐總結(jié)

    提升吞吐率。- Linux內(nèi)核中有很多網(wǎng)絡(luò)相關(guān)的參數(shù),我們可以根據(jù)不同的應(yīng)用場景,不同的塊大小來調(diào)整這些網(wǎng)絡(luò)參數(shù),以達(dá)到最優(yōu)的性能。- 中斷也是網(wǎng)絡(luò)
    發(fā)表于 07-05 14:26

    infosphere CDC 性能調(diào)優(yōu)及MC性能指標(biāo)監(jiān)控

    infosphere CDC 性能調(diào)優(yōu)及MC性能指標(biāo)監(jiān)控
    發(fā)表于 09-07 09:26 ?4次下載
    infosphere CDC 性能<b class='flag-5'>調(diào)</b><b class='flag-5'>優(yōu)</b>及MC性能指標(biāo)<b class='flag-5'>監(jiān)控</b>

    機(jī)器學(xué)習(xí)如何調(diào)優(yōu)數(shù)據(jù)

    在延遲方面,相比 Postgres 默認(rèn)配置,OtterTune、調(diào)優(yōu)工具、DBA 和 RDS 的配置獲得了近似的提升。我們大概可以把這歸于 OLTP-Bench 客戶端和 DBMS 之間的網(wǎng)絡(luò)開銷
    發(fā)表于 11-07 13:50 ?1121次閱讀
    機(jī)器學(xué)習(xí)如何<b class='flag-5'>調(diào)</b><b class='flag-5'>優(yōu)</b><b class='flag-5'>數(shù)據(jù)</b>庫

    如何對(duì)電機(jī)進(jìn)行調(diào)優(yōu)?調(diào)優(yōu)的好處是什么?

    如何自動(dòng)對(duì)電機(jī)進(jìn)行調(diào)優(yōu)
    的頭像 發(fā)表于 08-22 00:03 ?3059次閱讀

    Linux網(wǎng)絡(luò)接收過程的監(jiān)控調(diào)優(yōu)

    、ksoftirqd軟中斷處理幾個(gè)過程。其中在ksoftirqd軟中斷處理中,把數(shù)據(jù)包從RingBuffer中摘下來,送到協(xié)議的處理,再之后送到用戶進(jìn)程socket的接收隊(duì)列中。 圖1 Li
    的頭像 發(fā)表于 11-10 14:50 ?1638次閱讀

    Linux查看資源使用情況和性能調(diào)優(yōu)常用的命令

    ,包括進(jìn)程、線程、程序堆棧、內(nèi)存、Swap、CPU調(diào)度、內(nèi)存調(diào)度、網(wǎng)絡(luò)連接和IO讀寫等。 本文介紹了Linux查看資源使用情況和性能調(diào)優(yōu)常用的命令,包括top、htop、ps、free
    的頭像 發(fā)表于 11-12 17:54 ?4145次閱讀

    Linux用電功耗調(diào)優(yōu)的筆記分享

    整理一些Linux用電功耗調(diào)優(yōu)的筆記,分享給小伙伴,關(guān)于用電調(diào)優(yōu)個(gè)人覺得
    的頭像 發(fā)表于 06-23 15:19 ?3935次閱讀

    Linux性能調(diào)優(yōu)常見工具和堆棧解析

    ? Linux系統(tǒng)性能調(diào)優(yōu)涉及多個(gè)方面,包括內(nèi)核參數(shù)調(diào)整、文件系統(tǒng)優(yōu)化、網(wǎng)絡(luò)設(shè)置等。 ? 1. 內(nèi)核參數(shù)調(diào)整:通過調(diào)整內(nèi)核參數(shù)來提高系統(tǒng)性能。例如,調(diào)整進(jìn)程調(diào)度策略、內(nèi)存管理參數(shù)等。
    的頭像 發(fā)表于 06-29 09:45 ?858次閱讀
    <b class='flag-5'>Linux</b>性能<b class='flag-5'>調(diào)</b><b class='flag-5'>優(yōu)</b>常見工具和堆棧解析

    Linux網(wǎng)絡(luò)技術(shù)的相關(guān)知識(shí)

    網(wǎng)絡(luò)是一個(gè)很復(fù)雜的協(xié)議,今天網(wǎng)絡(luò)這么發(fā)達(dá),網(wǎng)絡(luò)協(xié)議起到關(guān)鍵性作用。 這里就給大家詳細(xì)描述一下:Linux
    的頭像 發(fā)表于 08-24 10:33 ?614次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>網(wǎng)絡(luò)</b>技術(shù)<b class='flag-5'>棧</b>的相關(guān)知識(shí)

    jvm調(diào)優(yōu)參數(shù)

    JVM(Java虛擬機(jī))是Java程序的運(yùn)行環(huán)境,它負(fù)責(zé)解釋Java字節(jié)碼并執(zhí)行相應(yīng)的指令。為了提高應(yīng)用程序的性能和穩(wěn)定性,我們可以調(diào)優(yōu)JVM的參數(shù)。 JVM調(diào)優(yōu)主要涉及到堆內(nèi)存、垃圾
    的頭像 發(fā)表于 12-05 11:29 ?555次閱讀

    jvm調(diào)優(yōu)主要是調(diào)哪里

    JVM調(diào)優(yōu)主要涉及內(nèi)存管理、垃圾回收、線程管理與鎖優(yōu)化等方面。下面將詳細(xì)介紹每個(gè)方面的調(diào)優(yōu)技術(shù)和策略以及如何進(jìn)行優(yōu)化。 內(nèi)存管理 JVM的內(nèi)存管理主要包括堆內(nèi)存、
    的頭像 發(fā)表于 12-05 11:37 ?1428次閱讀

    jvm調(diào)優(yōu)工具有哪些

    JVM調(diào)優(yōu)是提高Java應(yīng)用程序性能的重要手段,而JVM調(diào)優(yōu)工具則是輔助開發(fā)人員進(jìn)行調(diào)優(yōu)工作的利
    的頭像 發(fā)表于 12-05 11:44 ?976次閱讀

    Linux網(wǎng)絡(luò)協(xié)議的實(shí)現(xiàn)

    網(wǎng)絡(luò)協(xié)議是操作系統(tǒng)核心的一個(gè)重要組成部分,負(fù)責(zé)管理網(wǎng)絡(luò)通信中的數(shù)據(jù)包處理。在 Linux 操作系統(tǒng)中,
    的頭像 發(fā)表于 09-10 09:51 ?194次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>網(wǎng)絡(luò)</b>協(xié)議<b class='flag-5'>棧</b>的實(shí)現(xiàn)