Upload
magoroku-yamamoto
View
2.646
Download
3
Embed Size (px)
Citation preview
20 分でわかった事にするPower Management
cpuidle 編@magoroku15 最底辺活動家
Androidzaurus のつぶやき
• われらの恐竜先生、販売日に Tegra 3 のタブレットをご購入
• 買った、直後の勉強会にて ustream 送出マシンとして華麗にデビュー
• 独自の視点での解析 - お約束ですね -
使用未許諾
Android Zairus の日記
使用未許諾
Governor は Interactive
What dose this mean?
Governor?
Power management ちょー入門
• 家庭のパワーマネジメント– 照明はコマメに消す– 冷房は設定温度を高めに→ 住人が決める・操作する
• CPU のパワーマネジメント– 不要なものは止める– 処理速度と落とす→ どうやって決めるのか?操作するの
か?
UNIX/BSD/Mac/Linux
KERNEL
App
HDD
System call
idle
動かすプロセスが無いと idle を呼ぶ
BSD 4.3
GENERIC/locore.c1498 .globl Idle1499 Idle: idle:1500 mtpr $0,$IPL # must allow interrupts here1501 tstl _whichqs # look for non-empty queue1502 bneq sw11503 brb idle
Tegra の idleKernel_V9_4_2_7/arch/arm/mach-tegrastatic int tegra_cpuidle_register_device(unsigned int cpu) //
cpuidleへの登録{
:state->enter = tegra_idle_enter_lp2;:
}static inline void tegra_idle_lp2(struct cpuidle_device *dev, struct cpuidle_state *state){#ifdef CONFIG_ARCH_TEGRA_2x_SOC // tegra2の場合 tegra2_idle_lp2(dev, state);#endif#ifdef CONFIG_ARCH_TEGRA_3x_SOC // tegra3の場合 tegra3_idle_lp2(dev, state);#endif}
Tegra3 の idleKernel_V9_4_2_7/arch/arm/mach-tegra/sleep.Svoid tegra3_idle_lp2(struct cpuidle_device *dev, struct cpuidle_state *state){ s64 request = ktime_to_us(tick_nohz_get_sleep_length()); bool last_cpu = tegra_set_cpu_in_lp2(dev->cpu);
cpu_pm_enter();
if (last_cpu && (dev->cpu == 0)) // CPU0だけ別扱い tegra3_idle_enter_lp2_cpu_0(dev, state, request); else tegra3_idle_enter_lp2_cpu_n(dev, state, request);
cpu_pm_exit(); tegra_clear_cpu_in_lp2(dev->cpu);}
Tegra3 の idleKernel_V9_4_2_7/arch/arm/mach-tegra/sleep.SENTRY(tegra_cpu_wfi) cpu_id r0 cpu_to_halt_reg r1, r0 cpu_to_csr_reg r2, r0 mov32 r0, TEGRA_FLOW_CTRL_VIRT mov r3, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG str r3, [r0, r2] @ clear event & interrupt status mov r3, #FLOW_CTRL_WAIT_FOR_INTERRUPT | FLOW_CTRL_JTAG_RESUME str r3, [r0, r1] @ put flow controller in wait irq
mode dsb wfi mov r3, #0 str r3, [r0, r1] @ clear flow controller halt status mov r3, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG str r3, [r0, r2] @ clear event & interrupt status dsb mov pc, lrENDPROC(tegra_cpu_wfi)
WFI Wait For Interrupt
• ARM の命令• 割り込が発生するまで、 CPU を低電力モードで命
令の実行を止める• 眠りの深さ / 寝起きの良さ– 深く眠ると
• 電力低減効果大 / 寝起きは悪い• もっさり
– 浅く眠ると• 電力低減効果小 / 寝起きは良い• さくさく
• WFI を呼ぶ前に眠りの深さを指定する
おっと• この時点で Tegra の State を理解していな
い事に気づく• Flow controller って何?
Omap3 の idleint __init omap3_idle_init(void){
:state->enter = (state->flags & CPUIDLE_FLAG_CHECK_BM) ?
omap3_enter_idle_bm : omap3_enter_idle;:
}
static int omap3_enter_idle(struct cpuidle_device *dev, struct cpuidle_state *state){
:}
omap3 のC - ステート#define OMAP3_STATE_C1 0 /* C1 - MPU WFI + Core active */
#define OMAP3_STATE_C2 1 /* C2 - MPU WFI + Core inactive */#define OMAP3_STATE_C3 2 /* C3 - MPU CSWR + Core inactive */#define OMAP3_STATE_C4 3 /* C4 - MPU OFF + Core iactive */#define OMAP3_STATE_C5 4 /* C5 - MPU RET + Core RET */#define OMAP3_STATE_C6 5 /* C6 - MPU OFF + Core RET */#define OMAP3_STATE_C7 6 /* C7 - MPU OFF + Core OFF */
昼寝IDLE
爆睡
ステートの指定はどうするの?• CPUIdle Framework– CPU依存の C ステート– Governor( 統治者 ) によるポリシーベースの管
理– /sys/power/cpuidle_deepest_state– /sys/proc/pm_prepwstst
• Governor– “ladder”,”menu”– drivers/cpuidle/governors
cpuidle の構成
/sys/devices/syste/cpu/cpuidle ユーザレベルインターフェース
menu ladder
Generic cpuidle
omap3-cpuidle tegra2-cpuidle
Governor
Cpuidle アーキ無依存
tegra3-cpuidle Cpuidle アーキ依存
cpuidle
• 実行可能なプロセスがない状態を管理– 昔は単純な停止 or ループ– ARM では命令を追加して明に idle を通知
WFI– WFI を呼ぶ前に、寝る深さ C-State を指定
• 標準で Ladder と menu の Governor– ユーザプログラムで統計情報から指定も可
• 他の省電力機能も cpuidle を起点に動作
他のフレームワーク• cpufreq– 動作周波数を変更– 電源電圧も合わせて変更
• runtime_pm– SoC 内部コアを機能単位ごとに停止するヒントを管理– SoC 内の機能毎に usecount を用意し、 idle のタイミ
ング未使用の機能を止める– Beagle の pm_branch で実機評価可能
• cpuhotplug– cpuidle の C-state 変更を CPU 単位に拡張
上級者向けの話題• Runtime_PM– http://elinux.org/OMAP_Power_Management– http://git.kernel.org/?p=linux/kernel/git/khilman/l
inux-omap-pm.git• Beagleboard で Sleep 時の電流を 8mW にし
た話– http://groups.google.com/group/beagleboard/bro
wse_thread/thread/197a8ef6b46cc828– 回路を改造して、ボード上のコントローラの
電源供給を止める
おわり