午夜网站国产欧美_加勒比视频亚洲无码_91亚洲人人在字幕国产_18禁止美女爆乳免费网站_被消防员c哭高h野外糙汉动漫_午夜精品视频在线无码_gogowww人体大胆裸体午液_2021自拍偷区亚洲综合第一页_国产欧美一区二区精品性色超碰_99國產精品無碼

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

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

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

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

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

  2. per-VMA lock

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

  4. Large folios/動(dòng)態(tài)大頁(yè)

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

  6. 基于scope的資源管理

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

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

  9. EEVDF調(diào)度

  10. BPF通用迭代器

下面我們一一展開。

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

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

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

這個(gè)patchset——sched: Implement BPF extensible scheduler class

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

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

2. 定制化調(diào)度行為:為特定應(yīng)用定制調(diào)度器(這個(gè)調(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)系,任何一個(gè)sched_class,都需要實(shí)現(xiàn)一系列的callback函數(shù),比如:


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

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

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

比如eBPF中可以pop一個(gè)BPF_MAP_TYPE_QUEUE類型的map:

而userspace則可以u(píng)pdate_elem相關(guān)dispatch進(jìn)程的pid到這個(gè)map:

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

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

per-VMA lock

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

但是之前我們?cè)趐age fault中,也是要拿mmap_sem讀鎖的,因?yàn)槲覀円膊恢纏age fault處理過程中,對(duì)應(yīng)的VMA會(huì)不會(huì)變化或者甚至消失,所以要和可能寫VMA的人排他。Page fault的處理邏輯實(shí)際是:

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

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

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

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

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

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

它的這個(gè)實(shí)現(xiàn)看起來很奇怪,因?yàn)樗玫搅藇ma->vm_lock->lock后,并不真地會(huì)一直拿著,而是馬上就放了up_write,但是它寫了一個(gè)vma->vm_lock_seq,把這個(gè)vm_lock_seq寫成了vma->vm_mm->mm_lock_seq的,而進(jìn)程級(jí)的mm_lock_seq會(huì)在mmap_lock釋放的時(shí)候自增。

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

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

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

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

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


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

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

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

Large folios/動(dòng)態(tài)大頁(yè)

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

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

歡迎登錄盛圖科技

歡迎注冊(cè)盛圖科技

已有賬號(hào),立即登錄