一、eBPF安全可觀測(cè)性的前景展望
本次分享將從監(jiān)控和可觀測(cè)性、eBPF安全可觀測(cè)性分析、內(nèi)核安全可觀測(cè)性展望三個(gè)方面展開(kāi)。
1.監(jiān)控(Monitoring)vs可觀測(cè)性(Observability)
從上圖可以看到,監(jiān)控只是可觀測(cè)性的冰山一角,而大部分都隱藏在水面之下的深層次問(wèn)題無(wú)法簡(jiǎn)單通過(guò)監(jiān)控解決。
目前監(jiān)控也開(kāi)始可視化,但絕大部分都是事先預(yù)定義參數(shù),然后事后查看日志,進(jìn)行分析。監(jiān)控的缺點(diǎn)包括:
可擴(kuò)展性差,需要修改代碼和編譯;驗(yàn)證周期長(zhǎng);數(shù)據(jù)來(lái)源窄等問(wèn)題。
可觀測(cè)性是通過(guò)主動(dòng)定制度量的搜集和內(nèi)核數(shù)據(jù)聚合,包括以下三種:
Logging
實(shí)時(shí)或者事后特定事件信息
分布式服務(wù)器集群的海量數(shù)據(jù)溯源圖
離散信息整理各種異步信息
Tracing
數(shù)據(jù)源:提供數(shù)據(jù)來(lái)源
采集框架:往上對(duì)接數(shù)據(jù)源,采集解析發(fā)送數(shù)據(jù),往下對(duì)用戶態(tài)提供接口
前端交互:對(duì)接Tracing內(nèi)核框架,直接與用戶交互,負(fù)責(zé)采集配置和數(shù)據(jù)分析
Metrics(度量)這也是可觀測(cè)性與監(jiān)控最主要的區(qū)別
系統(tǒng)中某一類信息的統(tǒng)計(jì)聚合,比如CPU、內(nèi)存、網(wǎng)絡(luò)吞吐、硬盤 I/O、硬盤使用等情況。當(dāng)度量值觸發(fā)異常閾值時(shí),系統(tǒng)可以發(fā)出告警信息或主動(dòng)處理,比如殺死或隔離進(jìn)程;
主要目的:監(jiān)控(Monitoring)和預(yù)警(Alert)
總結(jié)一下監(jiān)控和觀測(cè)的區(qū)別:
監(jiān)控:收集和分析系統(tǒng)數(shù)據(jù),查看系統(tǒng)當(dāng)前的狀態(tài),對(duì)可預(yù)見(jiàn)的問(wèn)題進(jìn)行分析處理;
可觀測(cè)性:通過(guò)觀察系統(tǒng)并衡量系統(tǒng)的內(nèi)部狀態(tài),從其外部輸出的數(shù)據(jù)推斷出來(lái)系統(tǒng)此時(shí)處于某種程度的度量,特別是我們所關(guān)心的場(chǎng)景和事件;
2.eBPF安全可觀測(cè)性分析
先簡(jiǎn)單定義下什么是安全:安全指的是某種對(duì)象或者對(duì)象屬性不受威脅的狀態(tài)。
所謂安全可觀測(cè)性:
通過(guò)觀測(cè)整個(gè)系統(tǒng),從低級(jí)別的內(nèi)核可見(jiàn)性到跟蹤文件訪問(wèn)、網(wǎng)絡(luò)活動(dòng)或能力(capability)變化,一直到應(yīng)用層,涵蓋了諸如對(duì)易受攻擊的共享庫(kù)的函數(shù)調(diào)用、跟蹤進(jìn)程執(zhí)行或解析發(fā)出的 HTTP 請(qǐng)求。因此這里的安全是整體的概念。
提供對(duì)各種內(nèi)核子系統(tǒng)的可觀測(cè)性,涵蓋了命名空間逃逸、Capabilities 和特權(quán)升級(jí)、文件系統(tǒng)和數(shù)據(jù)訪問(wèn)、HTTP、DNS、TLS 和 TCP 等協(xié)議的網(wǎng)絡(luò)活動(dòng),以及系統(tǒng)調(diào)用層的事件,以審計(jì)系統(tǒng)調(diào)用和跟蹤進(jìn)程執(zhí)行。
從日志、跟蹤及度量三個(gè)維度檢查相關(guān)輸出,進(jìn)而來(lái)衡量系統(tǒng)內(nèi)部安全狀態(tài)的能力。
eBPF的安全可觀測(cè)性表現(xiàn)為對(duì)內(nèi)核來(lái)說(shuō)其存在感極低但觀測(cè)能力卻異常強(qiáng)大(藥效好,副作用小):
程序沙箱化:通過(guò)eBPF驗(yàn)證器保護(hù)內(nèi)核穩(wěn)定運(yùn)行。
侵入性低:無(wú)須修改內(nèi)核代碼,且無(wú)須停止程序運(yùn)行。
透明化:從內(nèi)核中透明搜集數(shù)據(jù),保證企業(yè)最重要的數(shù)據(jù)資產(chǎn)。
可配置:Cilium等自定義乃至自動(dòng)化配置策略,更新靈活性高,過(guò)濾條件豐富。
快速檢測(cè):在內(nèi)核中直接處理各種事件,不需要回傳用戶態(tài),使得異常檢測(cè)方便和快速。
其中的程序沙箱話離不開(kāi)更安全的eBPF Verifier(其中最重要的是邊界檢查):
擁有加載eBPF程序的流程所需的特權(quán)
無(wú)crash或其他異常導(dǎo)致系統(tǒng)崩潰的情況
程序可以正常結(jié)束,無(wú)死循環(huán)
檢查內(nèi)存越界
檢查寄存器溢出
eBPF的可觀測(cè)性應(yīng)用場(chǎng)景主要有以下三類:
1.云原生容器的安全可觀測(cè)性、
這也是傳統(tǒng)BPF基于網(wǎng)絡(luò)應(yīng)用場(chǎng)景的進(jìn)一步發(fā)展:
隨著云網(wǎng)邊端的急速發(fā)展,人們的目光越發(fā)的聚焦在目前最火熱的云原生場(chǎng)景上。Falco、Tracee、Tetragon、Datadog-agent、KubeArmor是現(xiàn)階段云原生場(chǎng)景下比較流行的幾款運(yùn)行時(shí)防護(hù)方案。
這些方案主要是基于eBPF掛載內(nèi)核函數(shù)并編寫過(guò)濾策略,在內(nèi)核層出現(xiàn)異常攻擊時(shí)觸發(fā)預(yù)置的策略,無(wú)需再返回用戶層而直接發(fā)出告警甚至阻斷。
以預(yù)防的方式在整個(gè)操作系統(tǒng)中執(zhí)行安全策略,而不是對(duì)事件異步地做出反應(yīng)。除了能夠?yàn)槎鄠€(gè)層級(jí)的訪問(wèn)控制指定允許列表外,還能夠自動(dòng)檢測(cè)特權(quán)和 Capabilities 升級(jí)或命名空間提權(quán)(容器逃逸),并自動(dòng)終止受影響的進(jìn)程。
安全策略可以通過(guò) Kubernetes(CRD)、JSON API 或 Open Policy Agent(OPA)等系統(tǒng)注入。
2.應(yīng)用層安全可觀測(cè)方案
3.內(nèi)核層安全可觀測(cè)方案
3.內(nèi)核安全可觀測(cè)性展望
下面從傳統(tǒng)內(nèi)核安全、Android內(nèi)核安全、KRSI等幾個(gè)方面展開(kāi)討論。
傳統(tǒng)內(nèi)核安全方案存在著諸多需要解決的問(wèn)題:
正如Linus Torvalds曾經(jīng)說(shuō)過(guò)的,大多數(shù)安全問(wèn)題都是bug造成的,而bug又是軟件開(kāi)發(fā)過(guò)程的一部分,是軟件就有bug。
至于是安全還是非安全漏洞bug,內(nèi)核社區(qū)的做法就是盡可能多的測(cè)試,找出更多潛在漏洞這樣近似于黑名單的做法。
內(nèi)核代碼提交走的流程比較繁瑣,應(yīng)用到具體內(nèi)核版本上,又存在周期長(zhǎng)以及版本適配的問(wèn)題,所以導(dǎo)致內(nèi)核在安全方面發(fā)展的速度明顯慢于其他模塊。同時(shí),隨著智能化、數(shù)字化、云化的飛速發(fā)展,全球基于Linux系統(tǒng)的設(shè)備數(shù)以百億計(jì),而這些設(shè)備的安全保障主要取決于主線內(nèi)核的安全性和健壯性,當(dāng)某一內(nèi)核LTS版本被發(fā)有漏洞,這樣相關(guān)的機(jī)器都會(huì)面臨被攻破利用的局面,損失難以估量。
嵌入式領(lǐng)域的Android內(nèi)核安全:
現(xiàn)如今,世界上越來(lái)越多的智能終端包括手機(jī)、TV、SmartBox和IoT、汽車、多媒體設(shè)備等等,均深度使用Android系統(tǒng),而Android的底層正是Linux內(nèi)核,這也讓Linux內(nèi)核的安全性對(duì)Android產(chǎn)生重大影響。
由于歷史原因,Google在Android內(nèi)核開(kāi)源的問(wèn)題上,理念和Linux內(nèi)核社區(qū)不是十分的匹配,這也導(dǎo)致了Android對(duì)內(nèi)核做了大量的針對(duì)性修改,但是無(wú)法合入到Upstream上。這也導(dǎo)致了Android內(nèi)核在安全側(cè)有部分不同于Linux內(nèi)核,側(cè)重點(diǎn)也存在不同。
在操作系統(tǒng)級(jí)別,Android平臺(tái)不僅提供Linux內(nèi)核的安全功能,而且還提供安全的進(jìn)程間通信 (IPC)機(jī)制,以便在不同進(jìn)程中運(yùn)行的應(yīng)用之間安全通信。操作系統(tǒng)級(jí)別的這些安全功能旨在確保即使是原生代碼也要受應(yīng)用沙盒的限制。無(wú)論相應(yīng)代碼是自帶應(yīng)用行為導(dǎo)致的結(jié)果,還是利用應(yīng)用漏洞導(dǎo)致的結(jié)果,系統(tǒng)都能防止違規(guī)應(yīng)用危害其他應(yīng)用、Android 系統(tǒng)或設(shè)備本身。
Android內(nèi)核安全特性:
HWAddressSanitizer(硬件支持的內(nèi)存檢測(cè)工具)
KASAN
Top-byte Ignore
KCFI(流控完整性校驗(yàn))
ShadowCallStack(堆棧保護(hù))
目前工作的關(guān)注重點(diǎn)是內(nèi)核安全可觀測(cè)性利器-KRSI:
KRSI (Kernel Runtime Security Instrumentation)的原型通過(guò)LSM (Linux security module)形式實(shí)現(xiàn),可以將eBPF program掛載到kernel的security hook(安全掛鉤點(diǎn))上。內(nèi)核的安全性主要包括兩個(gè)方面:Signals和Mitigations,這兩者密不可分。
Signals:意味著系統(tǒng)有一些異常活動(dòng)的跡象、事件
Mitigations:在檢測(cè)到異常行為之后所采取的告警或阻斷措施
KRSI基于LSM來(lái)實(shí)現(xiàn),這也就使其能夠進(jìn)行訪問(wèn)控制策略的決策,但這不是KRSI的工作重心,主要是為了全面監(jiān)視系統(tǒng)行為,以便檢測(cè)攻擊(最重要的應(yīng)用場(chǎng)景,但目前主要還是只做檢測(cè)居多,因?yàn)橘Q(mào)然做阻斷處理可能會(huì)比較危險(xiǎn))。從這種角度來(lái)看,KRSI可以說(shuō)是內(nèi)核審計(jì)機(jī)制的擴(kuò)展,使用eBPF來(lái)提供比目前內(nèi)核審計(jì)子系統(tǒng)更高級(jí)別的可配置性。
KRSI工具可以看作是eBPF和LSM的強(qiáng)強(qiáng)聯(lián)合:KRSI = eBPF + LSM
1.KRSI允許適當(dāng)?shù)奶貦?quán)用戶將BPF程序掛載到LSM子系統(tǒng)提供的數(shù)百個(gè)鉤子中的任何一個(gè)上面。
2.為了簡(jiǎn)化這個(gè)步驟,KRSI在/sys/kernel/security/bpf下面導(dǎo)出了一個(gè)新的文件系統(tǒng)層次結(jié)構(gòu)——每個(gè)鉤子對(duì)應(yīng)一個(gè)文件。
3.可以使用bpf()系統(tǒng)調(diào)用將BPF程序(新的BPF_PROG_TYPE_LSM 類型)掛載到這些鉤子上,并且可以有多個(gè)程序掛載到任何給定的鉤子。
4.每當(dāng)觸發(fā)一個(gè)安全鉤子時(shí),將依次調(diào)用所有掛載的BPF程序,只要任一BPF程序返回錯(cuò)誤狀態(tài),那么請(qǐng)求的操作將被拒絕。
5.KRSI能夠從函數(shù)級(jí)別做阻斷操作,相比進(jìn)程具有更細(xì)粒度,危險(xiǎn)程度也會(huì)小得多。
后續(xù)計(jì)劃
內(nèi)核安全問(wèn)題是個(gè)非常復(fù)雜的話題,牽一發(fā)而動(dòng)全身,防御機(jī)制、加固配置、漏洞利用等等挑戰(zhàn)性的技術(shù)。在進(jìn)行加固防御的過(guò)程中,又會(huì)產(chǎn)生性能或者系統(tǒng)穩(wěn)定性相關(guān)的影響。
從eBPF + LSM的角度可以更加可視化、數(shù)據(jù)豐富的觀測(cè)內(nèi)核安全情況,進(jìn)而在內(nèi)核Livepatch、漏洞檢測(cè)以及防御提權(quán)相關(guān)攻擊手段上,有著進(jìn)一步的發(fā)展空間。
二、Linux進(jìn)程調(diào)度與性能優(yōu)化
本次分享將從進(jìn)程調(diào)度概念、進(jìn)程調(diào)度框架、進(jìn)程調(diào)度算法和性能優(yōu)化四個(gè)方面展開(kāi)。
1.進(jìn)程調(diào)度概念
最初的Linux只有進(jìn)程,task_struct相當(dāng)于進(jìn)程控制塊(PCB),后來(lái)出現(xiàn)了線程,task_struct就開(kāi)始對(duì)應(yīng)線程。Linux沒(méi)有從概念上直接區(qū)分兩者,如果不同的task_struct間共享資源,它們屬于同一進(jìn)程中的線程,否則就屬于不同的進(jìn)程。
這里要注意,用戶態(tài)中的進(jìn)程和線程與內(nèi)核態(tài)間的映射關(guān)系:用戶態(tài)函數(shù)getpid()得到的是內(nèi)核中的tgid;用戶態(tài)函數(shù)gettid()得到的是內(nèi)核中的pid。
Posix支持一級(jí)調(diào)度和二級(jí)調(diào)度兩種模式,二級(jí)調(diào)度會(huì)先調(diào)度進(jìn)程,然后才是進(jìn)程中的線程。而Linux選擇的是直接調(diào)度線程的一級(jí)調(diào)度,效率會(huì)比二級(jí)調(diào)度高。
Linux進(jìn)程調(diào)度體系如下圖:
CPU資源管理器(what):調(diào)度器(scheduler)就是CPU資源管理器,因?yàn)椴僮飨到y(tǒng)的重要作用之一是管理各種系統(tǒng)資源,而CPU是其中最重要的資源。常用直接共享型資源的管理方法有時(shí)分、空分、獨(dú)占等,IO一般是獨(dú)占資源,內(nèi)存支持空分管理,而CPU只支持時(shí)分,因此這種時(shí)分管理方法就是進(jìn)程調(diào)度。
為什么要及為什么能調(diào)度(why):
為什么要調(diào)度:宏觀并行,微觀串行,支持多任務(wù)的協(xié)作與搶占。最初是協(xié)作,后來(lái)為了防止個(gè)別進(jìn)程長(zhǎng)期霸占CPU,引入了搶占機(jī)制。
為什么能調(diào)度:包括主動(dòng)調(diào)度和被動(dòng)調(diào)度,線程上下文可切換。
調(diào)度時(shí)機(jī)(when):
主動(dòng)調(diào)度:通過(guò)主動(dòng)調(diào)用sched_yield的自愿性主動(dòng)調(diào)度,以及進(jìn)程由于等待資源而阻塞的非自愿性主動(dòng)調(diào)度。
被動(dòng)調(diào)度:
觸發(fā)點(diǎn):設(shè)置 TIF_NEED_RESCHED 標(biāo)志,主要是時(shí)鐘中斷和喚醒搶占。
執(zhí)行點(diǎn):檢查 TIF_NEED_RESCHED 標(biāo)志 和 滿足preempt_count == 0的條件。
主要包括以下四種場(chǎng)景:
系統(tǒng)調(diào)用完成返回用戶空間
完成返回用戶空間
中斷完成返回內(nèi)核空間
出禁用搶占臨界區(qū)
如何進(jìn)行調(diào)度(how):調(diào)用pick_next_task()選擇下一個(gè)調(diào)度進(jìn)程和通過(guò)context_switch切換進(jìn)程(上下文:內(nèi)存空間,寄存器和棧)。
下面按時(shí)間順序簡(jiǎn)單介紹一下linux調(diào)度器的發(fā)展歷史:
傳統(tǒng)Unix調(diào)度器:區(qū)分IO密集型和CPU密集型,但全局只有一個(gè)未排序的運(yùn)行隊(duì)列,多CPU會(huì)有競(jìng)爭(zhēng),而且調(diào)度選擇需要遍歷整個(gè)隊(duì)列,復(fù)雜度為O(n)。
O(1)調(diào)度器:運(yùn)行隊(duì)列從全局變成每個(gè)CPU一個(gè),鏈表分成活動(dòng)和過(guò)期兩個(gè)數(shù)組,引入位圖,復(fù)雜度降為為O(1)。
SD調(diào)度器:考慮到會(huì)因?yàn)閭€(gè)別進(jìn)程的偽裝而造成的實(shí)際調(diào)度不公平,不再區(qū)分IO和CPU密集型,未合入內(nèi)核。
RSDL調(diào)度器:組時(shí)間配額,有點(diǎn)像Cgroup,但未合入內(nèi)核。
CFS(完全公平調(diào)度器):從SD/RSDL中吸取了完全公平的思想,目前內(nèi)核主流調(diào)度器。
可以從以下幾個(gè)方面來(lái)評(píng)價(jià)調(diào)度器:
1.響應(yīng)性:存在大量人機(jī)交互的PC和手機(jī)要重視響應(yīng)。
2.吞吐量:服務(wù)器更關(guān)心吞吐量,而提高響應(yīng)性會(huì)增加進(jìn)程切換的評(píng)論,也就會(huì)降低吞吐量。所以響應(yīng)和吞吐是一對(duì)矛盾。
3.公平性:相對(duì)公平,實(shí)際和理論的運(yùn)行時(shí)間應(yīng)該相符。
4.適應(yīng)性:也就是可擴(kuò)展性。
5.節(jié)能性:智能手機(jī)的需求,需要通過(guò)調(diào)度均衡來(lái)省電。
2.進(jìn)程調(diào)度框架
如下圖所示,Linux一共有5個(gè)調(diào)度類:(stop和idle每個(gè)CPU一個(gè))
stop:無(wú)調(diào)度策略,用戶空間不可用,內(nèi)核用來(lái)處理線程遷移等優(yōu)先級(jí)極高的事情。
idle:無(wú)調(diào)度策略,用戶空間不可用,無(wú)其他進(jìn)程調(diào)用時(shí)才調(diào)用idle進(jìn)程。
deadline:硬實(shí)時(shí),要在確定時(shí)延內(nèi)完成調(diào)度。
realtime:軟實(shí)時(shí),盡力而為保證實(shí)時(shí)性。
time-share:按優(yōu)先級(jí)分配時(shí)間片。
調(diào)度類之間的關(guān)系:除非資源限制,優(yōu)先調(diào)度高優(yōu)先級(jí)進(jìn)程。但要注意,Linux考慮到在惡劣環(huán)境下,普通進(jìn)程應(yīng)該仍有被調(diào)度的機(jī)會(huì),會(huì)默認(rèn)預(yù)留有5%的帶寬給普通進(jìn)程。
如下圖所示,從用戶空間到內(nèi)核空間,進(jìn)程優(yōu)先級(jí)會(huì)發(fā)生轉(zhuǎn)換:
用戶空間優(yōu)先級(jí):分為1~99優(yōu)先級(jí)從低到高的實(shí)時(shí)進(jìn)程,以及nice值-20~19動(dòng)態(tài)優(yōu)先級(jí)從高到低的分時(shí)進(jìn)程。
映射到內(nèi)核空間優(yōu)先級(jí)分為三步:
1.實(shí)時(shí)優(yōu)先級(jí):實(shí)時(shí)進(jìn)程不變,分時(shí)進(jìn)程從動(dòng)態(tài)優(yōu)先級(jí)映射為100~139靜態(tài)優(yōu)先級(jí)由高到低。
2.規(guī)范優(yōu)先級(jí):實(shí)時(shí)進(jìn)程映射為-1~98優(yōu)先級(jí)由高到低,99為空,分時(shí)進(jìn)程靜態(tài)優(yōu)先級(jí)不變。
3.動(dòng)態(tài)優(yōu)先級(jí):可以看到動(dòng)態(tài)優(yōu)先級(jí)幾乎等于規(guī)范優(yōu)先級(jí),只有在解決優(yōu)先級(jí)反轉(zhuǎn)問(wèn)題時(shí)采用優(yōu)先級(jí)繼承策略時(shí)才會(huì)變化,此時(shí)會(huì)體現(xiàn)為動(dòng)態(tài)優(yōu)先級(jí)。
注意:-1和-2分別對(duì)應(yīng)deadline和stop的邏輯優(yōu)先級(jí)。
那如何進(jìn)行進(jìn)程切換呢?
切換用戶空間:不同進(jìn)程的用戶空間不同,需要切換。
切換內(nèi)核棧:不同進(jìn)程共享內(nèi)核空間,但需要切換內(nèi)核棧。進(jìn)程切換就像火車切換軌道,換道后,車上的人感覺(jué)火車沒(méi)變,但是因?yàn)檐壍雷兞耍谐桃簿透兞恕>€程的執(zhí)行過(guò)程就是函數(shù)調(diào)用樹的深度優(yōu)先遍歷,進(jìn)程的切換點(diǎn)是__schedule函數(shù),該函數(shù)前半部分在進(jìn)程A的調(diào)用棧上執(zhí)行,后半部分就跑到進(jìn)程B的調(diào)用棧上執(zhí)行了,返回則在新進(jìn)程上執(zhí)行。
3.進(jìn)程調(diào)度算法
CFS調(diào)度器定義:通過(guò)引入虛擬運(yùn)行時(shí)間vruntime(realtime / weight),每次選擇vruntime最小的進(jìn)程(紅黑樹來(lái)管理)來(lái)調(diào)度,在真實(shí)硬件上模擬理想多任務(wù)處理器。
枯燥的定義不太容易理解的話,下面我們通過(guò)一個(gè)與實(shí)際生活比較貼近的例子來(lái)解釋CFS調(diào)度模型。
請(qǐng)仔細(xì)觀察上圖,圖中事物與進(jìn)程調(diào)度的映射關(guān)系如下:
水杯:表示進(jìn)程,蓋子打開(kāi)的水杯表示進(jìn)程處于就緒和執(zhí)行狀態(tài),其中Ready Table上的水杯都是就緒態(tài)進(jìn)程,水龍頭下的水杯是運(yùn)行態(tài)進(jìn)程。蓋子閉合的表示阻塞態(tài)的進(jìn)程,它們都在不同的Wait Box中。
水杯的粗細(xì):表示不同的優(yōu)先級(jí)。
watermark:表示虛擬運(yùn)行時(shí)間vruntime,min watermark會(huì)被pick to run。
Ready Table:表示可運(yùn)行隊(duì)列rq。
Wait Box:表示不同Event對(duì)應(yīng)的等待隊(duì)列,如果只能由對(duì)應(yīng)的Event喚醒的話,就屬于不可中斷的深睡眠,否則就是也可由signal喚醒的可中斷淺睡眠。
水龍頭:表示CPU,水龍頭中放出來(lái)的水就是CPU時(shí)間。
操作pick to run的手:表示調(diào)度算法,如果調(diào)度過(guò)于頻繁,那杯子接的水就少,水龍頭的水掉地上浪費(fèi)了(響應(yīng)好但性能差);反之調(diào)度周期長(zhǎng)的話,杯子接的水太多會(huì)造成不平均(性能好但響應(yīng)差)。權(quán)衡下來(lái)既不能接太少,最小值就是調(diào)度粒度;也不能接太多,最大值就是時(shí)間片。
這里需要特別注意的幾點(diǎn):
1.進(jìn)程的狀態(tài)
注意區(qū)別進(jìn)程的5種狀態(tài)中的運(yùn)行態(tài)和就緒態(tài),所有就緒態(tài)進(jìn)程都位于cpu的運(yùn)行隊(duì)列中,而每個(gè)cpu上當(dāng)前只有一個(gè)運(yùn)行態(tài)進(jìn)程。可以看到下面的代碼分別通過(guò)on_rq和on_cpu來(lái)確定進(jìn)程是runnable的就緒態(tài)還是running的運(yùn)行態(tài)。對(duì)應(yīng)上面的例子,桌子上的開(kāi)口水杯表示就緒(on_rq),水龍頭下的開(kāi)口水杯表示運(yùn)行(on_cpu)。
2.優(yōu)先級(jí)與權(quán)重
CFS中的nice值會(huì)提前轉(zhuǎn)換為權(quán)重,nice的范圍是 [-20 -- 19],為了使得兩個(gè)相鄰的權(quán)重的占比差為10%,將以nice 0 為基準(zhǔn)轉(zhuǎn)化為1024,整個(gè)數(shù)列是以1.25為公比的等比數(shù)列。將原來(lái)的等差數(shù)列轉(zhuǎn)為等比數(shù)列,因?yàn)檎{(diào)度策略的絕對(duì)值不重要,相對(duì)值(比例)才重要。
3.調(diào)度周期
調(diào)度周期 = 調(diào)度粒度 * 就緒和運(yùn)行進(jìn)程的數(shù)量,對(duì)應(yīng)上面的例子就是所有開(kāi)蓋玻璃杯數(shù)量(桌子上和水龍頭下的)與調(diào)度粒度的乘積,等于調(diào)度周期(所有杯子都接了一次水)。最小調(diào)度周期等于最小粒度乘以數(shù)量,如果計(jì)算算出來(lái)的時(shí)間片小于最小調(diào)度周期,內(nèi)核就會(huì)讓時(shí)間片直接等于最小調(diào)度周期。
4.調(diào)度延遲
調(diào)度延遲是另一個(gè)概念,對(duì)應(yīng)上面的例子就是從開(kāi)口玻璃杯放到到桌子上開(kāi)始計(jì)算,到送到水龍頭下接水的時(shí)間。但要注意,Linux中的調(diào)度延遲卻不這個(gè)意思,內(nèi)核代碼體現(xiàn)的調(diào)度延遲是最小調(diào)度周期,也就是調(diào)度周期的最小值。
4.性能優(yōu)化
單個(gè)進(jìn)程的性能優(yōu)化:
對(duì)于單個(gè)進(jìn)程來(lái)說(shuō),可以通過(guò)下面的系統(tǒng)調(diào)用來(lái)改變進(jìn)程(線程)的調(diào)度策略和優(yōu)先級(jí),只有特權(quán)進(jìn)程才能調(diào)高自己的調(diào)度策略或者優(yōu)先級(jí)。一般不要輕易地把進(jìn)程設(shè)置為實(shí)時(shí)進(jìn)程或者提高其優(yōu)先級(jí),除非有充足的理由。
系統(tǒng)響應(yīng)性與吞吐量的優(yōu)化:
系統(tǒng)的響應(yīng)性和吞吐量是一對(duì)矛盾,很多時(shí)候我們要根據(jù)具體的情況來(lái)對(duì)系統(tǒng)進(jìn)行配置。CONFIG_PREEMPT:是否開(kāi)啟內(nèi)核搶占,開(kāi)啟可增加響應(yīng)性,不開(kāi)啟可增加吞吐量。一般服務(wù)器系統(tǒng)不會(huì)開(kāi)啟,桌面和移動(dòng)系統(tǒng)會(huì)開(kāi)啟。
定時(shí)器tick頻率HZ:
定時(shí)器tick的頻率HZ,對(duì)系統(tǒng)的響應(yīng)性和吞吐量也有很大的影響,HZ取值較大,系統(tǒng)響應(yīng)性好,但是吞吐量會(huì)降低,HZ取值較小,吞吐量會(huì)增大,但是響應(yīng)性會(huì)降低。
避免實(shí)時(shí)進(jìn)程過(guò)度占用CPU:
為此內(nèi)核提供了一對(duì)參數(shù),可以設(shè)置一個(gè)運(yùn)行周期內(nèi),實(shí)時(shí)進(jìn)程最多只能用多少CPU時(shí)間,這樣就可以給普通進(jìn)程留下一些執(zhí)行時(shí)間。這兩個(gè)參數(shù)對(duì)應(yīng)的文件是:
/proc/sys/kernel/sched_rt_period_us/proc/sys/kernel/sched_rt_runtime_us
可以通過(guò)cat和echo來(lái)查看和設(shè)置具體的值,單位是微妙默認(rèn)值分別是1000000,950000,也就是說(shuō)在每一秒內(nèi)實(shí)時(shí)進(jìn)程最多運(yùn)行0.95s,會(huì)給普通進(jìn)程保留0.5s。當(dāng)然如果此時(shí)沒(méi)有普通進(jìn)程,實(shí)時(shí)進(jìn)程還是可以使用100%的CPU時(shí)間的。如果我們不希望實(shí)時(shí)進(jìn)程使用過(guò)多的CPU時(shí)間的話,可以修改這個(gè)值。
子進(jìn)程是否優(yōu)先運(yùn)行的問(wèn)題:
默認(rèn)情況下父進(jìn)程與剛fork出來(lái)的子進(jìn)程,誰(shuí)會(huì)先得到執(zhí)行是不確定的。如果在我們的環(huán)境中經(jīng)常會(huì)fork子進(jìn)程,并且我們總是希望子進(jìn)程比父進(jìn)程先得到執(zhí)行,那么我們可以將/proc/sys/kernel/sched_child_runs_first值設(shè)為1。
更多信息可以來(lái)這里獲取==>>電子技術(shù)應(yīng)用-AET<<