每一個(gè) CPU 核心都會(huì)有一個(gè) idle 進(jìn)程,idle 進(jìn)程是當(dāng)系統(tǒng)沒有調(diào)度 CPU 資源的時(shí)候,會(huì)進(jìn)入 idle 進(jìn)程,而 idle 進(jìn)程的作用就是不使用 CPU,以此達(dá)到省電的目的。
在ARM64架構(gòu)中,當(dāng)CPU Idle時(shí),會(huì)調(diào)用WFI指令(wait for interrupt),關(guān)掉CPU的Clock以便降低功耗,當(dāng)有外設(shè)中斷觸發(fā)時(shí),CPU又會(huì)恢復(fù)回來。
cpuidle core 是 cpuidle framework 的核心模塊,負(fù)責(zé)抽象出 cpuidle device、cpuidle driver 和 cpuidle governor 三個(gè)實(shí)體,如下所示:
cpuidle core 抽象出了 cpuidle device、cpuidle driver 和 cpuidle governor 三個(gè)數(shù)據(jù)結(jié)構(gòu)。
數(shù)據(jù)結(jié)構(gòu)
cpuidle_device
針對(duì)每個(gè)CPU核都對(duì)應(yīng)一個(gè)struct cpuidle_device結(jié)構(gòu),主要字段介紹如下
structcpuidle_device{ //該cpu核是否注冊(cè)進(jìn)內(nèi)核中 unsignedintregistered:1; //該cpu核是否已經(jīng)使能 unsignedintenabled:1; unsignedintuse_deepest_state:1; //對(duì)應(yīng)的cpunumber unsignedintcpu; //該cpu核上一次停留在cpuidle狀態(tài)的時(shí)間(us) intlast_residency; //記錄每個(gè)cpuidle狀態(tài)的統(tǒng)計(jì)信息,包括是否使能、進(jìn)入該cpuidle狀態(tài)的次數(shù),停留在該cpuidle狀態(tài)的總時(shí)間(us) structcpuidle_state_usagestates_usage[CPUIDLE_STATE_MAX]; ...... };
對(duì)應(yīng)的注冊(cè)接口是 cpuidle_register_device。
cpuidle_driver
cpuidle driver用于驅(qū)動(dòng)一個(gè)或多個(gè)CPU核,關(guān)鍵字段描述如下:
structcpuidle_driver{ constchar*name; structmodule*owner; intrefcnt; //用于驅(qū)動(dòng)注冊(cè)時(shí)判斷是否需要設(shè)置broadcasttimer unsignedintbctimer:1; //用于描述cpuidle的狀態(tài),需要按照功耗從大到小來排序,具體有多少個(gè)cpuidle狀態(tài) structcpuidle_statestates[CPUIDLE_STATE_MAX]; ...... };
//CPU有多種不同的idle級(jí)別。這些idle級(jí)別有不同的功耗和延遲,從而可以在不同的場(chǎng)景下使用 //主要包括exit_latency、power_usage、target_residency。這些特性是governor制定idle策略的依據(jù) structcpuidle_state{ charname[CPUIDLE_NAME_LEN]; chardesc[CPUIDLE_DESC_LEN]; unsignedintflags; //CPU從該idle state下返回運(yùn)行狀態(tài)的延遲,單位為us。它決定了CPU在idle狀態(tài)和run狀態(tài)之間切換的效率,如果延遲過大,將會(huì)影響系統(tǒng)性能; unsignedintexit_latency;/*inUS*/ //CPU在該idlestate下的功耗,單位為mW intpower_usage;/*inmW*/ //期望的停留時(shí)間,單位為us。進(jìn)入和退出idle state是需要消耗額外的能量的,如果在idle狀態(tài)停留的時(shí)間過短,節(jié)省的功耗少于額外的消耗,則得不償失。governor會(huì)根據(jù)該字段,結(jié)合當(dāng)前的系統(tǒng)情況(如可以idle多久),選擇idle level; unsignedinttarget_residency;/*inUS*/ booldisabled;/*disabledonallCPUs*/ //進(jìn)入該state的回調(diào)函數(shù) int(*enter)(structcpuidle_device*dev, structcpuidle_driver*drv, intindex); //CPU長(zhǎng)時(shí)間不需要工作時(shí)(稱作offline),可調(diào)用該回調(diào)函數(shù)。 int(*enter_dead)(structcpuidle_device*dev,intindex); ...... };
對(duì)應(yīng)的注冊(cè)接口是 cpuidle_register_driver。
cpuidle_governor
governor 結(jié)構(gòu)主要提供不同的回調(diào)函數(shù),最終由 menu_governor 填充,主要字段如下:
structcpuidle_governor{ charname[CPUIDLE_NAME_LEN]; structlist_headgovernor_list; //governor的級(jí)別,正常情況下,kernel會(huì)選擇系統(tǒng)中rating值最大的governor作為當(dāng)前governor unsignedintrating; //在設(shè)備驅(qū)動(dòng)注冊(cè)和注銷的時(shí)候調(diào)用 int(*enable)(structcpuidle_driver*drv, structcpuidle_device*dev); void(*disable)(structcpuidle_driver*drv, structcpuidle_device*dev); //根據(jù)當(dāng)前系統(tǒng)的運(yùn)行狀況,以及各個(gè)idlestate的特性,選擇一個(gè)state(即決策) int(*select)(structcpuidle_driver*drv, structcpuidle_device*dev, bool*stop_tick); //通過該回調(diào)函數(shù),可以告知governor,系統(tǒng)上一次所處的idlestate是哪個(gè) void(*reflect)(structcpuidle_device*dev,intindex); };
對(duì)應(yīng)的注冊(cè)接口是 cpuidle_register_governor。
流程
我們先看下設(shè)備和驅(qū)動(dòng)的注冊(cè)過程:
注冊(cè)之后便將設(shè)備和驅(qū)動(dòng)建立起連接關(guān)系了,最終 cpuidle framework 的用戶便可通過接口來調(diào)用下層的接口,進(jìn)而完成具體的硬件操作。
下面看下 CPU 進(jìn)入 idle 狀態(tài)的流程圖:
可以看出,最終是通過 PSCI 來實(shí)現(xiàn) CPU 的 suspend。
PSCI
PSCI, Power State Coordination Interface,由ARM定義的電源管理接口規(guī)范,通常由Firmware來實(shí)現(xiàn),而Linux系統(tǒng)可以通過smc/hvc指令來進(jìn)入不同的Exception Level,進(jìn)而調(diào)用對(duì)應(yīng)的實(shí)現(xiàn)。
PSCI 支持如下功能:
CPU hotplug (on/off)
CPU idle (suspend/resume)
System suspend/resume
System shutdown and reset
每個(gè)功能和ATF之間的調(diào)用接口如下所示:
審核編輯:劉清
-
ARM
+關(guān)注
關(guān)注
134文章
9027瀏覽量
366491 -
電源管理
+關(guān)注
關(guān)注
115文章
6140瀏覽量
144107 -
cpu
+關(guān)注
關(guān)注
68文章
10805瀏覽量
210847
原文標(biāo)題:CPU 進(jìn)入 IDLE 都做了啥?
文章出處:【微信號(hào):LinuxDev,微信公眾號(hào):Linux閱碼場(chǎng)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論