之前介紹了電源的開機和關機重啟,本小節開始介紹省電的技術,其中最暴力的省電方法就是直接拔核hotplug處理,就像需要10個人干活都要吃飯,但是現在活少了最節省的方法就是砍掉幾個人,有點像裁員啊。
1. 省電技術概覽
?對于省電,我們短時間不使用設備的時候可以進行休眠喚醒,長時間不使用就直接關機了。在使用設備的時候可以按照當前需要的性能進行調頻處理就是CPUFreq和DevFeq,當沒重度使用或者只運行系統必須進程的時候可以進行CPU休閑(CPUIdle)、CPU熱插拔(CPU Hotplug)、CPU隔離(Core Isolate)和動態PM(Runtime PM)。
CPUIdle指的是當某個CPU上沒有進程可調度的時候可以暫時局部關掉這個CPU的電源,從而達到省電的目的,當再有進程需要執行的時候再恢復電源。
CPU Hotplug指的是我們可以把某個CPU熱移除,然后系統就不會再往這個CPU上派任務了,這個CPU就可以放心地完全關閉電源了,當把這個CPU再熱插入之后,就對這個CPU恢復供電,這個CPU就可以正常執行任務了。
CPU隔離指的是我們把某個CPU隔離開來,系統不再把它作為進程調度的目標,這樣這個CPU就可以長久地進入Idle狀態了,達到省電的目的。不過CPU隔離并不是專門的省電機制,我們把CPU隔離之后還可以通過set_affinity把進程專門遷移到這個CPU上,這個CPU還會繼續運行。CPU隔離能達到一種介于CPUIdle和CPU熱插拔之間的效果。
Runtime PM指的是設備的動態電源管理,系統中存在很多設備,但是并不是每種設備都在一直使用,比如相機可能在大部分時間都不會使用,所以我們可以在大部分時間把相機的電源關閉,在需用相機的時候,再給相機供電。
cpu hotplug和idle的區別?
hotplug是從硬件上拔掉核下電,idle只是從軟件上進行處理,也就是說調度器在idle時只是不去調用但是核還是可見的,hotplug直接沒這個核了,軟件完全不可見。
?省電管理可以達到省電的目的,但是也會降低系統的性能,包括響應延遲、帶寬、吞吐量等。所以內核又提供了一個PM QoS框架,QoS是Quality Of Service(服務質量)。PM QoS框架一面向顧客提供接口,顧客可以通過這些接口對系統的性能提出要求,一面向各種省電機制下發要求,省電機制在省電的同時也要滿足這些性能要求。PM QoS的顧客包括內核和進程:對于內核,PM QoS提供了接口函數可以直接調用;對于進程,PM QoS提供了一些設備文件可以讓用戶空間進行讀寫。PM QoS對某一項性能指標的要求叫做一個約束,約束分為系統級約束和設備級約束。系統級約束針對的是整個系統的性能要求,設備級約束針對的是某個設備的性能要求。
整體上電源管理也是策略和機制分離的,例如:
hotplug是一個機制,誰去用?可以用戶App制定的策略、溫控策略、系統suspend時需要等。
CPUFreq是策略和機制都包含的。
2. 熱插拔代碼介紹
cpu的狀態包括:possible、present、online、active。
possible狀態的cpu:可理解為存在這個CPU資源,但還沒有納入Kernel的管理范圍。
present狀態的cpu:表示已經被kernel接管。
online狀態的cpu:表示可以被調度器使用。
active狀態的cpu:表示可以被遷移migrate。
?Linux內核在初始的時候,會創建虛擬總線cpu_subsys,每個cpu調用register_cpu注冊時,都會將cpu設備掛在這個總線下。cpu的拔插是通過操作文件節點online實現的,具體拔插操作如下(以cpu1為例):
echo0>/sys/devices/system/cpu/cpu1/online//拔核操作 echo1>/sys/devices/system/cpu/cpu1/online//插核操作
為什么以cpu1為例?
Linux CPU熱插拔,支持在系統啟動后,關閉任意一個secondary cpu(在ARM架構中,CPU0為boot cpu,不能被關閉),并在需要時重新打開它。
當操作/sys/devices/system/cpu/cpu1/online文件的時候,會執行drivers/base/core.c中online_store()函數
staticssize_tonline_store(structdevice*dev,structdevice_attribute*attr, constchar*buf,size_tcount ) { boolval; intret; ret=strtobool(buf,&val); if(ret0) ????????????????return?ret; ????????ret?=?lock_device_hotplug_sysfs(); ????????if?(ret) ????????????????return?ret; ????????ret?=?val???device_online(dev)?:?device_offline(dev); ????????unlock_device_hotplug(); ????????return?ret?0???ret?:?count; } static?DEVICE_ATTR_RW(online);
?這塊有一個sysfs的知識點,就是DEVICE_ATTR_RW(online);聲明了這個宏,就可以在文件系統里面為這個設備熟悉添加一個文件,當向這個文件寫入字符串的時候就會調用拼接出來的online_store()函數,讀這個文件的時候就會調用online_show()函數
#define__ATTR(_name,_mode,_show,_store){ .attr={.name=__stringify(_name), .mode=VERIFY_OCTAL_PERMISSIONS(_mode)}, .show=_show, .store=_store, } #define__ATTR_RW(_name)__ATTR(_name,0644,_name##_show,_name##_store) #defineDEVICE_ATTR_RW(_name) structdevice_attributedev_attr_##_name=__ATTR_RW(_name)
在online_store()函數中,拔核就執行device_offline(dev)函數
device_offline中dev->bus->offline(dev);
drivers/base/cpu.c中
structbus_typecpu_subsys={ .name="cpu", .dev_name="cpu", .match=cpu_subsys_match, #ifdefCONFIG_HOTPLUG_CPU .online=cpu_subsys_online, .offline=cpu_subsys_offline, #endif };
cpu_device_down cpu_down cpu_down_maps_locked _cpu_down cpuhp_down_callbacks takedown_cpu
[CPUHP_TEARDOWN_CPU]={ .name="cpu:teardown", .startup.single=NULL, .teardown.single=takedown_cpu, .cant_stop=true, },
do_idle狀態機會調用
arch_cpu_idle_dead cpu_die cpu_die psci_cpu_die psci_ops.cpu_off psci_0_2_cpu_off
?psci_0_2_cpu_off會調用__psci_cpu_off(PSCI_0_2_FN_CPU_OFF, state);最終發送smc指令給ATF,上面的cpu down流程匯總如下圖:
cpu up流程:
具體代碼自己加log,或者打斷點看好些。
3. ATF中處理
之前在電源管理入門-1關機重啟詳解中介紹的PSCI協議部分,這里會發送smc指令到ATF。在ATF中同理,會處理這些PSCI協議,這里不詳細介紹了。
后記
?本篇文章嘗試用markdown進行編寫,圖片用Midjourney生成,感覺效果還可以,之前每篇文章的排版很費時間。markdown可以只保留最小的一些格式,把注意力關注到文章內容本身,提高效率才能多寫一些文章進行更新。
審核編輯:湯梓紅
-
電源管理
+關注
關注
115文章
6177瀏覽量
144450 -
cpu
+關注
關注
68文章
10854瀏覽量
211587 -
Linux
+關注
關注
87文章
11292瀏覽量
209334 -
熱插拔
+關注
關注
2文章
224瀏覽量
37316
原文標題:電源管理入門-3 CPU熱插拔hotplug
文章出處:【微信號:OS與AUTOSAR研究,微信公眾號:OS與AUTOSAR研究】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論