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

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

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

朱輝:Linux Kernel iowait 時(shí)間的代碼原理以及內(nèi)核拓展文章介紹

Linux閱碼場(chǎng) ? 2018-01-05 10:09 ? 次閱讀

作者簡(jiǎn)介

朱輝,做過幾年模擬器,做過幾年GDB,在小米電視做過幾年Linux內(nèi)核優(yōu)化,主要圍繞MM。

現(xiàn)在在HyperHQ當(dāng)軟件工程師。

之前在我熱愛的公眾號(hào)Linuxer看到The precise meaning of I/O wait time in Linux 這篇文章,感覺寫的不錯(cuò),就是沒有落實(shí)到源碼上感覺稍微有點(diǎn)晦澀,于是自己讀了一下代碼。

當(dāng)task發(fā)生iowait的時(shí)候,內(nèi)核對(duì)他們的處理方法是將task切換出去,讓可運(yùn)行的task先運(yùn)行,而在切換出去前,會(huì)將其in_iowait設(shè)置為1,再次被喚醒的時(shí)候in_iowait被設(shè)置為原值。相關(guān)函數(shù)io_schedule,io_schedule_timeout,mutex_lock_io,mutex_lock_io_nested。

例如:

朱輝:Linux Kernel iowait 時(shí)間的代碼原理以及內(nèi)核拓展文章介紹

由此可見in_iowait表明了這個(gè)task是否在iowait。

另外要注意的是,這幾個(gè)切換函數(shù)除了mutex_lock_io,mutex_lock_io_nested會(huì)設(shè)置task運(yùn)行狀態(tài)為TASK_UNINTERRUPTIBLE外,內(nèi)核在調(diào)用io_schedule,io_schedule_timeout前都會(huì)設(shè)置task運(yùn)行狀態(tài)TASK_UNINTERRUPTIBLE。

在進(jìn)程切換函數(shù)__schedule在切換task的時(shí)候,如果被切換出的task的in_iowait為真,則會(huì)對(duì)這個(gè)CPU的運(yùn)行隊(duì)列rq結(jié)構(gòu)中的nr_iowait加1。

因?yàn)榍懊鎸?duì)task已經(jīng)被設(shè)置為TASK_UNINTERRUPTIBLE,則task需要被喚醒,對(duì)nr_iowait的減少操作也是在task喚醒函數(shù)來做的。

由此可見nr_iowait可以表明某CPU上是否有task在iowait,以及數(shù)量。

因?yàn)樘幱趇owait的task是TASK_UNINTERRUPTIBLE狀態(tài),其并不在就緒隊(duì)列中,所以其也沒有被CPU負(fù)載均衡到其他CPU的可能,所以nr_iowait也不需要處理負(fù)載均衡問題。

當(dāng)累加系統(tǒng)idle時(shí)間的時(shí)候,如果CPU的nr_iowait為真,也就是當(dāng)前這個(gè)cpu有task在等待iowait,則記錄為iowait時(shí)間。

在打開NO_HZ的內(nèi)核中,相關(guān)代碼在update_ts_time_stats。

朱輝:Linux Kernel iowait 時(shí)間的代碼原理以及內(nèi)核拓展文章介紹

而沒打開的則在 account_idle_time。

朱輝:Linux Kernel iowait 時(shí)間的代碼原理以及內(nèi)核拓展文章介紹

當(dāng)相關(guān)/proc/stat接口被訪問時(shí),get_iowait_time就會(huì)訪問這個(gè)時(shí)間并返回。

綜上所述,iowait時(shí)間就是CPU idle時(shí)間,但是這時(shí)候CPU上不是完全沒TASK需要運(yùn)行,而是休眠的task中有一個(gè)或者若干個(gè)是iowait的task。

當(dāng)然idle和iowait的時(shí)候CPU上還有idle task。

最后推薦一篇阿里內(nèi)核組的文章作為擴(kuò)展閱讀Kernel Documents/new iowait calculation

比較有意思是這里:

+ wait_event_interruptible_hrtimeout(ctx->wait,

+ aio_read_events(ctx, min_nr, nr, event, &ret), until);

無論超時(shí)值until是什么值,都會(huì)調(diào)用wait_event_interruptible_hrtimeout,雖然是hrtimer實(shí)時(shí)性已經(jīng)很高,但是在用來實(shí)際處理wait的宏__wait_event_hrtimeout可以看到hrtimer初始化使用的是:

hrtimer_start_range_ns(&__t.timer, timeout,

current->timer_slack_ns,

HRTIMER_MODE_REL);

其中第三個(gè)參數(shù)current->timer_slack_ns是傳遞給hrtimer的觸發(fā)范圍,因?yàn)閔rtimer實(shí)時(shí)性高,但是頻繁觸發(fā)系統(tǒng)顯然受不了,所以每次hrtimer觸發(fā)都會(huì)將時(shí)間范圍內(nèi)的timer都處理掉(見__hrtimer_run_queues)。所以timeout+current->timer_slack_ns才是設(shè)置的hrtimer的最后觸發(fā)時(shí)間,current->timer_slack_ns的默認(rèn)值是50000,也就是代表50000納秒。也就是這個(gè)時(shí)鐘最久會(huì)在50000納秒后觸發(fā),當(dāng)然也可能被之前的hrtimer觸發(fā)。

所以在wait_event_interruptible_hrtimeout中,一旦ctx->wait未能就緒,即使設(shè)置超時(shí)時(shí)間為0,也很可能要調(diào)用一次schedule,這導(dǎo)致iowait時(shí)間相差很大,也還很大幅度傷害了性能。

而這個(gè)問題也被5f785de588735306ec4d7c875caf9d28481c8b21進(jìn)行了修復(fù),這段代碼改成了:

- wait_event_interruptible_hrtimeout(ctx->wait,

- aio_read_events(ctx, min_nr, nr, event, &ret), until);

+ if (until.tv64 == 0)

+ aio_read_events(ctx, min_nr, nr, event, &ret);

+ else

+ wait_event_interruptible_hrtimeout(ctx->wait,

+ aio_read_events(ctx, min_nr, nr, event, &ret),

+ until);

從而在until為0的時(shí)候,直接調(diào)用aio_read_events。應(yīng)該就不會(huì)再有那么明顯的iowait問題了,另外也因此這個(gè)修復(fù)讓io_getevents的調(diào)用得到了超過百倍的性能提升。

當(dāng)然這個(gè)iowait不夠精確的原因還是存在,一旦因?yàn)樾枰l(fā)生task切換,還是會(huì)有不夠精確的問題。

最后要吐槽一下aio的設(shè)計(jì),都aio了還需要wait嗎?

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

    關(guān)注

    3

    文章

    1336

    瀏覽量

    40084
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11123

    瀏覽量

    207910
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4671

    瀏覽量

    67765

原文標(biāo)題:朱輝(茶水): Linux Kernel iowait 時(shí)間的代碼原理

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

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    如何編譯Linux Kernel

    整個(gè)Linux內(nèi)核編譯的過程非常簡(jiǎn)單,但是內(nèi)核編譯需要花費(fèi)很長的時(shí)間。因?yàn)?b class='flag-5'>Linux內(nèi)核
    發(fā)表于 06-07 16:26 ?9968次閱讀
    如何編譯<b class='flag-5'>Linux</b> <b class='flag-5'>Kernel</b>

    [分享資料]Linux Kernel Development Third Edition (Linux內(nèi)核設(shè)計(jì)與實(shí)現(xiàn))

    、進(jìn)程調(diào)度、時(shí)間管理和定時(shí)器、系統(tǒng)調(diào)用接口、內(nèi)存尋址、內(nèi)存管理和頁緩存、VFS、內(nèi)核同步以及調(diào)試技術(shù)等。同時(shí)《Linux內(nèi)核設(shè)計(jì)與實(shí)現(xiàn)(原書
    發(fā)表于 09-12 00:17

    編譯你自己的Linux內(nèi)核Kernel

    摘要:你馬上就會(huì)發(fā)現(xiàn),你也可以獲得(get),配置(configure),編譯(compile)和安裝(install)屬于你自己的Linux內(nèi)核Kernel)。目錄:引言安裝內(nèi)核
    發(fā)表于 11-10 12:16

    介紹一下Linux內(nèi)核編譯和更新的操作流程

    rk3399-firefly-linux.img -j4命令開始編譯內(nèi)核?! ?b class='flag-5'>內(nèi)核編譯時(shí)間視電腦配置而定,內(nèi)核
    發(fā)表于 06-21 09:58

    Linux內(nèi)核代碼漫游

    Linux內(nèi)核代碼漫游 本章試圖以順序的方式來解釋Linux代碼,以幫助讀者對(duì)源代碼的體系
    發(fā)表于 02-09 15:27 ?26次下載

    linux內(nèi)核kernel-api

    linux內(nèi)核kernel-api,不知道從哪兒找的了,但是你如果想要做內(nèi)核編程,這是一部api函數(shù)詳盡的工具書?。?!五星推薦
    發(fā)表于 10-30 17:16 ?19次下載

    怎樣去讀Linux內(nèi)核代碼

    怎樣去讀Linux內(nèi)核代碼
    發(fā)表于 10-25 10:15 ?13次下載
    怎樣去讀<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>源<b class='flag-5'>代碼</b>

    linux kernel工作隊(duì)列及源碼解析

    1. 前言 工作隊(duì)列(workqueue)的Linux內(nèi)核中的定義的用來處理不是很緊急事件的回調(diào)方式處理方法。 以下代碼linux內(nèi)核版本
    發(fā)表于 10-27 10:19 ?0次下載

    嵌入式未來還是Linux的天下,并通過內(nèi)核學(xué)習(xí)來闡述kernel的機(jī)理

    Kernel入門,要選本好的入門書籍,我從網(wǎng)上download一本《Linux內(nèi)核設(shè)計(jì)與實(shí)現(xiàn)》。這本書簡(jiǎn)單易讀,有OS基礎(chǔ)和Linux應(yīng)用基礎(chǔ)的人一讀即懂,我現(xiàn)已閱過3章,感覺很不錯(cuò),
    的頭像 發(fā)表于 01-24 08:47 ?3676次閱讀

    Linux Kernel 5.2.2震撼發(fā)布!

    在首個(gè)維護(hù)版本更新之后,在kernel.org官網(wǎng)上已經(jīng)將Linux Kernel 5.2分支標(biāo)記為“Stable”,意味著已經(jīng)準(zhǔn)備好大規(guī)模部署了,所有GNU/Linux發(fā)行版本都應(yīng)該
    的頭像 發(fā)表于 08-09 17:01 ?2800次閱讀

    快速理解什么是Linux內(nèi)核以及Linux內(nèi)核的內(nèi)容

    01 前言 本文主要講解什么是Linux內(nèi)核,以及通過多張圖片展示Linux內(nèi)核的作用與功能,以便于讀者能快速理解什么是
    的頭像 發(fā)表于 10-21 12:02 ?4144次閱讀
    快速理解什么是<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b><b class='flag-5'>以及</b><b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>的內(nèi)容

    自由軟件媒體Linux Kernel 5.10華為代碼貢獻(xiàn)排名第一

    ?自由軟件媒體 LWN.netLinux Kernel 5.10 代碼貢獻(xiàn),華為排名第一 在 Linux Kernel 5.10(下文簡(jiǎn)稱“5.10 版本”)版本中,華為提交的補(bǔ)丁數(shù)量
    的頭像 發(fā)表于 01-15 14:05 ?2578次閱讀
    自由軟件媒體<b class='flag-5'>Linux</b> <b class='flag-5'>Kernel</b> 5.10華為<b class='flag-5'>代碼</b>貢獻(xiàn)排名第一

    Linux_Kernel_Developments內(nèi)核開發(fā)

    Linux_Kernel_Developments內(nèi)核開發(fā)詳細(xì)說明。
    發(fā)表于 04-07 14:27 ?37次下載
    <b class='flag-5'>Linux_Kernel</b>_Developments<b class='flag-5'>內(nèi)核</b>開發(fā)

    Linux 6.1發(fā)布,微軟貢獻(xiàn)Linux內(nèi)核代碼

    此外,公告中并沒有提及 Linux 6.1 是否是 LTS 版本。按照 Linux 內(nèi)核維護(hù)者 Greg Kroah-Hartman 的說法,Linux
    的頭像 發(fā)表于 12-14 09:54 ?1080次閱讀

    Linux內(nèi)核代碼的靜態(tài)檢查

    Linus在2004年開發(fā)了kernel代碼靜態(tài)檢查工具,可以檢查出kernel中潛在的風(fēng)險(xiǎn)代碼
    的頭像 發(fā)表于 06-05 14:50 ?884次閱讀