shedu domain内核定义的结构体如下:
sd\sg\sgc
初始化的时候所有的cpu都在一个sceduling domain上面,那后面是需要将这个不同的cpu分配到不同的domain上去了。
然后开始build schedule domain
这个是MTK的一个芯片,但是大致可以看出DIE和MC的层级结构
build domian主要就是填充sg、sd还有sgc这些数据结构了,build domain的初始化主要包含四个部分
domian的初始化、group的初始化、group power的初始化、domian关联对应的队列。
线程
首先是分配空间
首先来看看这个结构体
struct sd_data {
struct sched_domain **__percpu sd;
struct sched_group **__percpu sg;
struct sched_group_capacity **__percpu sgc;
};
struct capacity_state {
unsigned long cap; /* compute capacity */
unsigned long power; /* power consumption at this compute capacity */
};
struct idle_state {
unsigned long power; /* power consumption in this idle state */
};
struct sched_group_energy {
unsigned int nr_idle_states; /* number of idle states */
struct idle_state *idle_states; /* ptr to idle state array */
unsigned int nr_cap_states; /* number of capacity states */
struct capacity_state *cap_states; /* ptr to capacity state array */
};
struct sched_domain_topology_level {
sched_domain_mask_f mask;
sched_domain_flags_f sd_flags;
sched_domain_energy_f energy;
int flags;
int numa_level;
struct sd_data data;
#ifdef CONFIG_SCHED_DEBUG
char *name;
#endif
};
初始化domain
成员 | 所属结构 | 含义 | 更新/获取函数 | 计算方法 |
rq->cpu_capacity_orig | rq | 本cpu总的计算能力 | init_sched_groups_capacity()/update_sd_lb_stats() -> update_group_capacity() -> update_cpu_capacity() | capacity = arch_scale_cpu_capacity(sd, cpu) |
rq->cpu_capacity | rq | 本cpu cfs的计算能力 = 总capacity - rt占用的capacity | init_sched_groups_capacity()/update_sd_lb_stats() -> update_group_capacity() -> update_cpu_capacity() | capacity *= scale_rt_capacity(cpu); |
rq->rd->max_cpu_capacity | rq->rd | root_domain中最大的cpu计算能力 | init_sched_groups_capacity()/update_sd_lb_stats() -> update_group_capacity() -> update_cpu_capacity() |
domain关联对应的工作队列
初始化时,初始化的cpu的online发生变化,会重新开始构建scheduling domain
// 系统启动时创建schedule domain的cpu发生变变化,会重新构建schedule domain
void __init sched_init_smp(void)
{
........
}
在内核提供的节点中只有一部分信息会以节点的形式输出出来,以8核cpu为例