深夜美女视频一区二区_91sao在线看片水片_亚洲日韩国语_精品中文字幕久久边人妻_高潮喷水香蕉视频色_白洁国产剧情Av手机在线_国产精品情侣呻吟_天空影院播放免费完整版视频_少妇高潮惨叫喷水在线观看_公交车大龟廷进我身体里

Hi,您好,歡迎來到西安盛圖軟件科技有限公司!

2023年度盤點|2023年Linux內(nèi)核十大技術(shù)革新功能

發(fā)布時間:2024-01-22 14:21:28

2023年,眾多Linux內(nèi)核開發(fā)者仍然在調(diào)度器、內(nèi)存管理、文件系統(tǒng)等領(lǐng)域貢獻著自己的idea和patch,本文從其中選取十個最典型的patchset,進行闡述,它們是:

  1. 基于eBPF的sched_ext調(diào)度類擴展

  2. per-VMA lock

  3. NUMA系統(tǒng)上kernel代碼段復(fù)制

  4. Large folios/動態(tài)大頁

  5. 文件系統(tǒng)large block支持

  6. 基于scope的資源管理

  7. 用代理執(zhí)行解決優(yōu)先級反轉(zhuǎn)(priority inversion)問題

  8. 延后用戶空間臨界區(qū)內(nèi)的搶占

  9. EEVDF調(diào)度

  10. BPF通用迭代器

下面我們一一展開。

基于eBPF的sched_ext調(diào)度類擴展

這一patchset的開發(fā)過程,堪稱神仙打架。對壘的多方,無論是發(fā)patch的還是review patch的,都是內(nèi)核社區(qū)的頂流大神,甚至連看客都會北冥神功。他們之間直接的拼殺,刺刀見紅,毫不留情,讓凡人們見識了神仙也有性格,技術(shù)和思想的力量可以怎樣無視虛偽和矯情。

sched_ext patchset由社區(qū)鼎鼎大名的Tejun Heo發(fā)出,他是Linux內(nèi)核cgroup、KERNFS、PER-CPU MEMORY ALLOCATOR、WORKQUEUE等的maintainer。

這個patchset——sched: Implement BPF extensible scheduler class

Patchset的實際貢獻還包括來自Google、meta、卡內(nèi)基梅隆大學(xué)等多家主流廠商和科研院校的開發(fā)者。該patchset擴展了一個調(diào)度class,與之前的CFS、realtime等并行,但是它允許調(diào)度行為被一個BPF程序來實現(xiàn),并聲稱有如下三大好處:

1.讓探索和實驗變地容易: 讓新的調(diào)度策略可以快速迭代

2. 定制化調(diào)度行為:為特定應(yīng)用定制調(diào)度器(這個調(diào)度器也許不適用于通用目的)

3. 調(diào)度器快速部署: 在產(chǎn)品環(huán)境下,非侵入式地修改調(diào)度器。

新加入的sched_ext與內(nèi)核已經(jīng)存在的stop_sched_class、dl_sched_class、rt_sched_class、fair_sched_class、idle_sched_class是一種并列關(guān)系,任何一個sched_class,都需要實現(xiàn)一系列的callback函數(shù),比如:


Patchset定義了一組可以由eBPF程序?qū)崿F(xiàn)的callback:

并在內(nèi)核的sched_ext class的callback中,調(diào)用這一組eBPF實現(xiàn)的callback,比如ext sched_class的select_task_rq() callback調(diào)用eBPF的select_cpu() callback:

進一步地,由于eBPF程序可以通過maps和userspace交互,實際上,調(diào)度行為也可以在userspace實現(xiàn)了,這讓內(nèi)核sched_class、eBPF的sched_ext_ops和用戶空間,實現(xiàn)了3位一體的聯(lián)動。

比如eBPF中可以pop一個BPF_MAP_TYPE_QUEUE類型的map:

而userspace則可以update_elem相關(guān)dispatch進程的pid到這個map:

整個patchset讓Linux內(nèi)核調(diào)度器的維護者Peter Zijlstra(同時也是ATOMIC INFRASTRUCTURE、CPU HOTPLUG、FUTEX、LKMM、MMU GATHER AND TLB INVALIDATION、Perf等的維護者)所極度反感,在patchset中直接給出了NACK:

他NAK的無疑是一位大神,當(dāng)我們回眸特洛伊之戰(zhàn)中兩位偉大英雄阿喀琉斯和赫克托耳的決斗時刻,最后命運的天平無論便向的是哪一邊,剩下的都只有悲壯。

per-VMA lock

如果Linux內(nèi)核里面有什么鎖最臭名昭著,那么一定是mmap_sem(后改名為mmap_lock)。這個鎖位于mm_struct里面,很顯然它應(yīng)該是一個多線程共享的進程級別概念而不應(yīng)該是per-VMA的概念:

但是之前我們在page fault中,也是要拿mmap_sem讀鎖的,因為我們也不知道page fault處理過程中,對應(yīng)的VMA會不會變化或者甚至消失,所以要和可能寫VMA的人排他。Page fault的處理邏輯實際是:

由于mmap_sem是整個進程的,而一個進程里面說不定也有成千上萬的VMA,然后大量的page fault以及其他的VMA的寫操作行為,相互競爭鎖,就導(dǎo)致大量的競爭延遲。其他需要持有寫鎖的地方也是非常多的,比如:brk、stack expand、munmap、remap_file_pages、exit、madvise、mprotect、mremap、mlock等。

用一個大的mmap_lock把這些寫和page fault的讀進行保護,這固然安全,但是也實在低效。我們假設(shè)一個進程有1萬個VMA,然后我們在其中的1個VMA上面進行page fault,其他的9999個VMA消失不消失,變化不變化,跟我這個page fault之間其實是沒有半毛錢關(guān)系的。如果能夠在PF中不去持有mmap_lock讀鎖,而去持有一個更細(xì)粒度的,只關(guān)心本VMA的鎖,應(yīng)該是一個更好的選擇。

在處理page fault的時候,我們只需要通過持有VMA的lock,來保證這個VMA本身的穩(wěn)定:

struct vm_area_struct *lock_vma_under_rcu(struct mm_struct *mm,            unsigned long address);

每個VMA里面實際增加了一個vma_lock(里面含有一個讀寫鎖):

在page fault里面我們持有讀鎖,在其他要寫某個VMA的場景,我們要持有寫鎖(前提條件是我們也必須持有了進程級的mmap_lock):

它的這個實現(xiàn)看起來很奇怪,因為它拿到了vma->vm_lock->lock后,并不真地會一直拿著,而是馬上就放了up_write,但是它寫了一個vma->vm_lock_seq,把這個vm_lock_seq寫成了vma->vm_mm->mm_lock_seq的,而進程級的mm_lock_seq會在mmap_lock釋放的時候自增。

但是拿讀鎖的page fault,則是在page fault的途中一直hold著vma->vm_lock->lock。lock_vma_under_rcu()會調(diào)用vma_start_read():

因為我們要開始VMA寫的時候把vma->vm_lock_seq寫成了進程級的mm_lock_seq,這樣當(dāng)我們拿讀鎖的時候,如果vma->vm_lock_seq == mm->mm_lock_seq,說明VMA還在寫,我們其實也不用拿讀鎖了,per-VMA讀鎖直接失敗,讓page fault的代碼回退到去拿原先的mmap_lock就好。

由于per-VMA拿寫鎖的人總是當(dāng)場放寫鎖,我們其實就不用擔(dān)心忘記up_write了。這有點自動化的類似后面將要提到的scope-based resource management。

值得一提是,在per-VMA lock準(zhǔn)備好之前,有些Linux內(nèi)核,比如Android采用了SPF(Speculative page faults)來處理page fault,SPF的實現(xiàn)不包含per-VMA lock,它也不拿mmap_sem,但是page fault會不拿mmap_sem投機執(zhí)行,處理過程中會邊走邊看,如果執(zhí)行過程中發(fā)現(xiàn)VMA被修改,page fault會拿mmap_sem來retry原先的page fault。這個機制我們在2022年終盤點中也有提及。

NUMA系統(tǒng)上kernel代碼段復(fù)制


Russell King,在Linux ARM體系架構(gòu)采用device tree之前,維護著ARM Linux社區(qū)。由于當(dāng)時的arch/arm目錄充斥著大量的冗余描述硬件的代碼,在2011年TI OMAP的一次Pull request中,Linus終于忍無可忍,破口大罵“this whole ARM thing is a f*cking pain in the ass”。此后,Linaro和ARM強勢介入,在ARM Linux引入了device tree,開啟了一個嶄新的時代。自己的地盤被人革了命,Russell童鞋的黯然神傷無可掩飾。但是,作為大神,Russell無疑擁有無可辯駁的技術(shù)實力,這次他給我們帶來的是黯然銷魂掌arm64 kernel text replication。

在一個典型的NUMA系統(tǒng)中,跨node訪問內(nèi)存的開銷比訪問本地node的開銷大。

于是從軟件層面,我們傾向于讓本node的CPU訪問本node的內(nèi)存,對于數(shù)據(jù)段而言,通過內(nèi)存綁定、NUMA balance等方法可以可以實現(xiàn)這個目的。
但是,Russell瞄準(zhǔn)的是內(nèi)核的代碼段,眾所周知,內(nèi)核代碼段在整個內(nèi)存只有一份拷貝,假設(shè)這份拷貝位于node 0 memory,那么對于node1,node 2, node3這些CPU而言,它們其實都是訪問遠(yuǎn)端的內(nèi)存來執(zhí)行內(nèi)核代碼,這顯然是有耗損的。
Russell的這個patchset ——arm64 kernel text replication
鏈接:
https://lore.kernel.org/linux-arm-kernel/ZMKNYEkM7YnrDtOt@shell.armlinux.org.uk/
讓kernel的代碼段(也可以包含只讀的數(shù)據(jù)段)在node0, node1, node2和node3各自擁有自己的拷貝,從而實現(xiàn)近距離內(nèi)存訪問。

Large folios/動態(tài)大頁

Large folios是社區(qū)2023的熱門話題,由于一個large folio中可以包含多個page,所以采用large folio可以減小page fault的次數(shù)(比如一個page fault中映射1個包含16個page的folio,這樣就減少了后面15次page fault)、降低LRU的維護成本(large folio整體加入LRU)、降低內(nèi)存的回收成本(large folio整體回收)等。

上一篇:21%程序員感覺到失業(yè)危機、AI崗成HR招聘難題,調(diào)查了13000名開發(fā)者后揭曉2024年技術(shù)招聘現(xiàn)狀!
下一篇:軟件工程--------就業(yè)與編程語言的多樣性選擇

歡迎登錄盛圖科技

歡迎注冊盛圖科技

已有賬號,立即登錄