cpu核心隔离和core_ctl
一、CPU拓扑信息由/sys/devices/system/cpu提供,包含下述文件
二、cpu核心隔离
kernel/sched/core.c
从这个函数中可以看到系统不会将所有的cpu隔离掉,会保留一个
/*
* 1) CPU is isolated and cpu is offlined:
* Unisolate the core.
* 2) CPU is not isolated and CPU is offlined:
* No action taken.
* 3) CPU is offline and request to isolate
* Request ignored.
* 4) CPU is offline and isolated:
* Not a possible state.
* 5) CPU is online and request to isolate
* Normal case: Isolate the CPU
* 6) CPU is not isolated and comes back online
* Nothing to do
*/
int sched_isolate_cpu(int cpu)
{
.........
/* We cannot isolate ALL cpus in the system */
if (cpumask_weight(&avail_cpus) == 1) {
--cpu_isolation_vote[cpu];
ret_code = -EINVAL;
goto out;
}
.........
}
三、cpufreq governor
cpufreq governor主要功能是根据特定的governor算法,计算cpu待切换频率对应的频点。当前内核支持performance、powersave、userspace、ondemand、conservative和schedutil六种governor。
其中前三种方式非常简单,如performance governor直接将cpu频率设置为最高值,powersave governor将频率设置为最低值,而userspace governor则将其设置为用户空间传入的频率值。
其它三种governor都会根据负载变化,动态调节cpu的频率,其特点分别如下:
(1)ondemand:当负载超过80%时,会将cpu的频率调到最高。否则就会按负载比例调节频率。它的调频方式比较激进,如负载升高时能快速升频,而频率负载降低时也会较快的降频。因此其可能导致cpu频繁进行升降频操作,造成性能抖动
(2)conservative:这种方式相对于ondemand,其调频方式更加柔和。它当负载超过80%时会以5%的幅度升频,而只有当负载低于20%时,才会以5%的幅度降频。因此其调频幅度较平滑,且降频时留有足够的缓冲,cpu不会频繁执行升降频操作。但它也使得cpu频率对负载的跟踪不够及时,特别是降频流程比较保守,从而可能会影响节电效果
(3)schedutil:以上两种方式中,负载都是由cpufreq模块自己计算的,它计算的主要依据为cpu idle时间。而实际上cpu在不同时间段idle时间,对当前负载的贡献是不同的,如1s前的负载显然比10s前负载贡献更大。
而实际上调度器本身就会跟踪cpu的负载,而且其负载跟踪算法(pelt)更加准确。因此若将调度器的负载值用作cpu调频依据,则不仅使cpu调频更加准确,而且还减少了cpufreq governor的负载计算流程,提高调频效率。schedutil就是使用这种方式实现调频的
四、core_ctl
参考链接:core ctrol框架的理解
1、Core_ctl的作用
core_ctl会根据当前系统的负载及运行任务数来动态的调节运行CPU的个数,从而降低功耗。主要通过下面的函数,如果active的cpu个数大于系统需要的cpu就隔离多余的cpu.否则解除隔离
static void __ref do_core_ctl(struct cluster_data *cluster) { unsigned int need; need = apply_limits(cluster, cluster->need_cpus); if (adjustment_possible(cluster, need)) { pr_debug("Trying to adjust group %u from %u to %u\n", cluster->first_cpu, cluster->active_cpus, need); if (cluster->active_cpus > need) //当cluster中active的cpu数目大于系统需要的CPU数目就会将多余的cpu进行隔离 try_to_isolate(cluster, need); else if (cluster->active_cpus < need) try_to_unisolate(cluster, need); } }
通过读core_ctl_isolated节点和每个cpu的隔离节点可知,core_ctl根据系统负载动态的将cpu5和cpu7进行了隔离,用于降低功耗。并不是由温控机制控制引起的核心隔离。
cpu*/isolate节点读到是实际隔离(物理上 已经隔离的)的cpu.
cooling_device/cur_state读到的核心隔离的值,是软件温控触发核心隔离的值。所以当判断是否是温控触发的cpu核心隔离,是需要度对应cool_device下的cur_state即可。
2、cluster的概念
(1)到底几个 cluster
可以查看cpufreq下有几个policy就有几个cluster.
policy0影响的是cpu0 cpu1 cpu2 cpu3
policy4影响的是cpu4 cpu5 cpu6
policy7影响的是cpu7
每个cpu可调整的频率和policy有关系。
(2)查看每个cluster下need_cpu和active_cpu的个数
我们可以看到第一个cluster的core_ctl的active_cpus为4就包括cpu0 cpu1 cpu2 cpu3,系统need的cpu为4个,need cpu=max cpu所以cpu0,1,2,3都需要处于正常工作状态。
第二个cluster有3个cpu,包括cpu4、cpu5、cpu6,系统need的是2个,cpu_max=3,总共有3个CPU,所以max cpu>need cpu,所以隔离了1个cpu后,active_cpus=2个。
第三个cluster只有cpu7,need_cpus=0,max_cpus=1,max_cpus>need_cpus所以我们要隔离这个cpu,隔离后,active_cpu=0.
所以最终结果8个cpu,系统通过core_ctl机制隔离了2个cpu,这两个不是有thermal机制触发的隔离。