本篇文章主要讲解4.9和4.14 Linux Kernel中sched_group拓扑关系建立过程。
在Linux Kernel中build_sched_domians()方法是真正开始建立调度域拓扑关系的函数,其中包括建立sched_group的拓扑关系:
static int build_sched_domains(const struct cpumask *cpu_map,
struct sched_domain_attr *attr)
{
......
/* Build the groups for the domains */
for_each_cpu(i, cpu_map) {
for (sd = *per_cpu_ptr(d.sd, i); sd; sd = sd->parent) {
sd->span_weight = cpumask_weight(sched_domain_span(sd));
if (sd->flags & SD_OVERLAP) {
if (build_overlap_sched_groups(sd, i))
goto error;
} else {
if (build_sched_groups(sd, i))
goto error;
}
}
}
......
}
该段代码的含义是:对于每个包含在cpu_map(即cpu_active_mask)中的CPU,遍历其在每个SDTL层级中的调度域,然后调用build_overlap_sched_groups()或build_sched_groups()方法建立该CPU在该SDTL层级下的sched_group的拓扑关系。假设SDTL只包含MC、DIE两个层级,则sched_group建立的拓扑关系如下图(本图来自《奔跑吧Linux内核》):
下面我们结合着sched_group的拓扑关系图主要分析build_sched_groups()方法的实现,首先分析4.9 Linux Kernel中的实现:
static int build_sched_groups(struct sched_domain *sd, int cpu)
{
struct sched_group *first = NULL, *last = NULL;
struct sd_data *sdd = sd->private;---------------------------1
const struct cpumask *span = sched_domain_span(sd);----------2
struct cpumask *covered;
int i;
get_group(cpu, sdd, &sd->groups);----------------------------3
atomic_inc(&sd->groups->ref);
if (cpu != cpumask_first(span))------------------------