linux 4.1.16 ftrace 进程调度,Linux内核进程调度overview(1)
一、概述
決定何時(shí)、如何選擇一個(gè)新進(jìn)程運(yùn)行的這組規(guī)則叫做:調(diào)度策略(scheduling policy)。
Linux的調(diào)度是基于分時(shí)技術(shù)(time sharing):多個(gè)進(jìn)程以“時(shí)間多路復(fù)用”方式運(yùn)行,因?yàn)镃PU的時(shí)間唄分成“片”(slice),給每個(gè)可運(yùn)行進(jìn)程分配一片。如果當(dāng)前運(yùn)行進(jìn)程的時(shí)間片或時(shí)限(quantum)到期時(shí),該進(jìn)程還沒(méi)有運(yùn)行完畢,進(jìn)程切換就會(huì)發(fā)生。
調(diào)度策略也是根據(jù)進(jìn)程的優(yōu)先級(jí)對(duì)它們進(jìn)行分類(lèi)。在Linux中,進(jìn)程優(yōu)先級(jí)是動(dòng)態(tài)的:在較長(zhǎng)時(shí)間內(nèi)沒(méi)有運(yùn)行的進(jìn)程,會(huì)動(dòng)態(tài)提升它們的優(yōu)先級(jí);相反地,對(duì)于在CPU上運(yùn)行較長(zhǎng)時(shí)間的進(jìn)程,會(huì)降低它們的優(yōu)先級(jí)來(lái)懲罰它們。
所以,實(shí)現(xiàn)調(diào)度的工具是調(diào)度器(scheduler),調(diào)度的對(duì)象是進(jìn)程(process),調(diào)度的方法是調(diào)度策略(包括調(diào)度算法)。
二、CPU調(diào)度器
這里主要講了cpu調(diào)度器的工作內(nèi)容和目的:
多個(gè)task會(huì)共享CPU資源
那如何進(jìn)行任務(wù)切換選擇呢?
當(dāng)前運(yùn)行的task中止
當(dāng)前運(yùn)行的task sleep(wait event)
新task創(chuàng)建,或者sleep的task喚醒了
當(dāng)前運(yùn)行的task的時(shí)間片用完
那調(diào)度器的目標(biāo)是什么?
公平調(diào)度各個(gè)task
基于task的優(yōu)先級(jí)來(lái)分配時(shí)間片
task的respnse時(shí)間短
高throughput(task執(zhí)行成功)
在多個(gè)cpu間,負(fù)載均衡
低功耗
調(diào)度器代碼運(yùn)行開(kāi)銷(xiāo)低
調(diào)度器會(huì)和工作在一些框架、服務(wù)器、PC、嵌入式/手機(jī)中。
三、O(1)調(diào)度器
在2.6.23(2007)以前,Linux調(diào)度器使用的是O(1)調(diào)度器:
調(diào)度器分140個(gè)優(yōu)先級(jí)等級(jí):0-99是RT task,100-139是User task
每個(gè)cpu的runqueue有2個(gè)數(shù)組:Active,Expaired
每個(gè)數(shù)組都有140個(gè)entry,對(duì)應(yīng)每個(gè)優(yōu)先級(jí)
每個(gè)entry是一條FIFO隊(duì)列結(jié)構(gòu)的鏈表
140位的bitmap用來(lái)檢測(cè)每個(gè)優(yōu)先級(jí)list
時(shí)間片會(huì)根據(jù)task的優(yōu)先級(jí)進(jìn)行分配
運(yùn)行時(shí)間expaire的task會(huì)從Active數(shù)組移動(dòng)到Expaired數(shù)組
當(dāng)Active數(shù)組為空時(shí),就交換2個(gè)數(shù)組。即,將Expaired數(shù)組變?yōu)锳ctive;Active(此時(shí)為空)變?yōu)镋xpaired
task的入rq和出rq,以及next task的選擇都是在固定時(shí)間內(nèi)完成
最后在O(1)調(diào)度器已經(jīng)被CFS替代。
四、當(dāng)前調(diào)度器架構(gòu)
在kernel 2.6.23(2007)后,由Ingo Molnar引入
在調(diào)度的class中,還存在調(diào)度policy
不同的調(diào)度class,高優(yōu)先級(jí)的,越早執(zhí)行
task可以在cpu、調(diào)度policy、調(diào)度class間進(jìn)行遷移
4.1? 調(diào)度class
由struce sched_class結(jié)構(gòu)體實(shí)現(xiàn):
structsched_class {const struct sched_class *next;void (*enqueue_task) (struct rq *rq, struct task_struct *p, intflags);void (*dequeue_task) (struct rq *rq, struct task_struct *p, intflags);
...struct task_struct * (*pick_next_task) (struct rq *rq, struct task_struct *prev, struct rq_flags *rf);
...
};
內(nèi)核中一共有5中調(diào)度class,優(yōu)先級(jí)從高到低:STOP > DL > RT > CFS > IDLE,他們通過(guò)鏈表實(shí)現(xiàn),并鏈接起來(lái)的。
4.2? 主調(diào)度函數(shù)Schedule()
內(nèi)核中進(jìn)程調(diào)度,最主要的實(shí)現(xiàn)是Schedule()函數(shù)。它完成如下工作:
選取下一個(gè)runnable的task,并將task放在cpu上運(yùn)行
按class優(yōu)先級(jí)搜索task來(lái)運(yùn)行,最先從STOP class開(kāi)始
輪詢(xún)搜索:for_each_class()
實(shí)現(xiàn)方式:pick_next_task():
again:
for_each_class(class) {
p= class->pick_next_task(rq, prev, rf);if(p) {if (unlikely(p ==RETRY_TASK))gotoagain;returnp;
}
}/*The idle class should always have a runnable task:*/BUG();
4.3? 調(diào)度class與policy
在不同的調(diào)度class下,可能會(huì)有不同的調(diào)度policy實(shí)現(xiàn):
● Stop
○ No policy
● Deadline
○ SCHED_DEADLINE
● Real Time
○ SCHED_FIFO
○ SCHED_RR
● Fair
○ SCHED_NORMAL
○ SCHED_BATCH
○ SCHED_IDLE
● Idle
○ No policy
不同的class代表不同的調(diào)度優(yōu)先級(jí);不同的policy同樣也意味著不同的調(diào)度方式。
4.4? 調(diào)度class:STOP
STOP類(lèi)型的class有如下特點(diǎn):
是最高優(yōu)先級(jí)的class(但是這個(gè)class不開(kāi)放給系統(tǒng)user使用的)
只能在smp系統(tǒng)上可用(stop_machine()在單核處理器下不可用)------括號(hào)內(nèi)的具體沒(méi)怎么理解
可以搶占所有task,并任何事件都不能搶占它
實(shí)現(xiàn)方式是:停止運(yùn)行的其他所有task,而在cpu上運(yùn)行一個(gè)特定的函數(shù)
沒(méi)有調(diào)度policy
屬于stop class的per cpu內(nèi)核線(xiàn)程:migration/N ------“N”為cpu core number
在以下情況下使用:task遷移、CPU hotplug、RCU、ftrace、cloclevents等
4.5? 調(diào)度class:Deadline(DL)
Deadline類(lèi)型的class有如下特點(diǎn):
在kernel 3.14(2013),由Dario Faggioli & Juri Lelli引入
在系統(tǒng)中,屬于可以使用的最高優(yōu)先級(jí)的class
調(diào)度policy為SCHED_DEADLINE
由紅黑樹(shù)結(jié)構(gòu)實(shí)現(xiàn)(自平衡樹(shù))
在以下情況下使用:周期性的實(shí)時(shí)task,例如:視頻編解碼
4.6? 調(diào)度Real-time(RT)
Real-time類(lèi)型的class有如下特點(diǎn):
符合POSIX標(biāo)準(zhǔn)要求
task優(yōu)先級(jí)范圍:0-99
優(yōu)先級(jí)在kernel和userspace中相反:0在kernel中,代表最高優(yōu)先級(jí);而在userspace中代表最低優(yōu)先級(jí)
相同優(yōu)先級(jí)下的調(diào)度policy:
SCHED_FIFO
SCHED_RR,默認(rèn)時(shí)間片長(zhǎng)度為100ms
由鏈表實(shí)現(xiàn)
在以下情況下使用:latency敏感的task,例如:IRQ threads
4.7? 調(diào)度CFS(Completely Fair Scheduler)
CFS類(lèi)型的class有如下特點(diǎn):
由Ingo Molnar引入
調(diào)度policy:
SCHED_NORMAL:普通task
SCHED_BATCH:批處理 task(batch task,非交互型)
SCHED_IDLE:低優(yōu)先級(jí)task
由紅黑樹(shù)結(jié)構(gòu)實(shí)現(xiàn)
跟蹤task的虛擬運(yùn)行時(shí)間(vruntime,task擁有的運(yùn)行時(shí)間)
虛擬運(yùn)行時(shí)間(vruntime)最短的task,最優(yōu)先運(yùn)行
task的優(yōu)先級(jí)作為權(quán)重,會(huì)影響虛擬運(yùn)行時(shí)間的計(jì)算(vruntime)
權(quán)重越大,虛擬運(yùn)行時(shí)間(vruntime)計(jì)算時(shí)的增量就越小
task的優(yōu)先級(jí)計(jì)算:120+nice值(nice范圍:-20 ~ +19)
用于所有其他類(lèi)型的task,例如:shell
4.7? 調(diào)度Idle
Idle類(lèi)型的class有如下特點(diǎn):
最低優(yōu)先級(jí)的調(diào)度class
沒(méi)有調(diào)度policy
屬于idle class的per cpu內(nèi)核線(xiàn)程(idle):swapper/N ------“N”為cpu core number
idle線(xiàn)程僅會(huì)在沒(méi)有其他task的情況下,在cpu上運(yùn)行
idle線(xiàn)程可以讓cpu進(jìn)入低功耗狀態(tài)
五、Runqueue
每個(gè)CPU都由一個(gè)struct rq的實(shí)例
每個(gè)”rq“包含了DL、RT、CFS的runqueue
Runnable的task會(huì)被壓入上面提到的那些runqueue中
在struct rq中由很多其他的信息和狀態(tài)
structrq {
...structcfs_rq cfs;structrt_rq rt;structdl_rq dl;
...
}
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的linux 4.1.16 ftrace 进程调度,Linux内核进程调度overview(1)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: oracle10g启动顺序,oracle
- 下一篇: 修改linux资源限制参数命令,linu