之前遇到一个耗电问题,最后发现是/proc/sys/kernel/sched_boost节点设置异常,一直处于boost状态。导致所有场景功耗上升。
现在总结一下sched_boost的相关知识。
Sched_Boost
sched_boost主要是通过影响Task placement的方式,来进行boost。它属于QTI EAS中的一部分。
默认task placement policy
计算每个cpu的负载,并将task分配到负载最轻的cpu上。如果有多个cpu的负载相同(一般是都处于idle),那么就会把task分配到系统中capacity最大的cpu上。
设置sched_boost
通过设置节点:/proc/sys/kernel/sched_boost 或者内核调用 sched_set_boost()函数,可以进行sched_boost,并且在分配任务时,忽略对energy的消耗。
boost一旦设置之后,就必须显示写0来关闭。同时也支持个应用同时调用设置,设置会选择boost等级最高的生效; 而当所有应用都都关闭boost时,boost才会真正失效。
boost等级
sched_boost一共有4个等级,除了0代表关闭boost以外,其他3个等级灵活地控制功耗和性能的不同倾向程度。
相关代码实现
static struct ctl_table kern_table[] = { //kernel/sysctl.c ...... { .procname = "sched_boost", .data = &sysctl_sched_boost, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = sched_boost_handler, //kernel/sched/boost.c .extra1 = &zero, .extra2 = &three, }, ...... };
在通过节点设置,会调用sched_boost_handler,sched_boost_handler中经过verify之后,调用_sched_set_boost来设置boost。
static void _sched_set_boost(int old_val, int type) { switch (type) { case NO_BOOST: /*0*/ if (old_val == FULL_THROTTLE_BOOST) /*1*/ core_ctl_set_boost(false); else if (old_val == CONSERVATIVE_BOOST) /*2*/ restore_cgroup_boost_settings(); else update_freq_aggregate_threshold(freq_aggr_threshold_backup); break; case FULL_THROTTLE_BOOST: /*1*/ core_ctl_set_boost(true); boost_kick_cpus(); break; case CONSERVATIVE_BOOST: /*2*/ update_cgroup_boost_settings(); boost_kick_cpus(); break; case RESTRAINED_BOOST: /*3*/ freq_aggr_threshold_backup = update_freq_aggregate_threshold(1); break; default: WARN_ON(1); return; } set_boost_policy(type); sysctl_sched_boost = type; trace_sched_set_boost(type); }
设置boost policy
在最后一步中,设置policy来体现task是否需要进行up migrate。如下是sched_boost不同等级对应的up migrate迁移策略。
Full throttle和Conservative:SCHED_BOOST_ON_BIG ---在进行task placement时,仅考虑capacity最大的cpu core
无:SCHED_BOOST_ON_ALL ---在进行task placement时,仅不考虑capacity最小的cpu core
No Boost和Restrained:SCHED_BOOST_NONE---正常EAS
static void set_boost_policy(int type) { if (type == SCHED_BOOST_NONE || type == RESTRAINED_BOOST) { //conservative(保守的)和full throttle(全油门)模式才会进行向上迁移 boost_policy = SCHED_BOOST_NONE; return; } if (boost_policy_dt) { boost_policy = boost_policy_dt; return; } if (min_possible_efficiency != max_possible_efficiency) { //左边是cpu中efficiency最小值,右边为最大值。big.LITTLE架构应该恒成立 boost_policy = SCHED_BOOST_ON_BIG; return; } boost_policy = SCHED_BOOST_ON_ALL; }
总结各个boost的效果
Full throttle:
1、通过core control,将所有cpu都进行unisolation
2、通过freq聚合,将load计算放大。从而触发提升freq,或者迁移等
3、通过设置boost policy= SCHED_BOOST_ON_BIG,迁移挑选target cpu时,只会选择大核
最终效果应该尽可能把任务都放在大核运行(除了cpuset中有限制)
Conservative:
1、通过更新group boost配置,仅让top-app和foreground组进行task placement boost
2、提高min_task_util的门限,让进行up migrate的条件更苛刻。只有load较大(>1ms)的task,会进行up migrate。
3、同上,更改min_task_util门限后,会提醒系统task与cpu是misfit,需要进行迁移。
4、通过设置boost policy= SCHED_BOOST_ON_BIG,迁移挑选target cpu时,只会选择大核
最终效果:top-app和foreground的一些task会迁移到大核运行
Restrained:
1、通过freq聚合,将load计算放大。从而触发提升freq,或者迁移等
load放大后,仍遵循基本EAS。提升freq或者迁移,视情况而定。
参考:
https://www.cnblogs.com/lingjiajun/p/12583220.html
https://www.cnblogs.com/lingjiajun/p/12317090.html