cpusets, isolcpus: exclude isolcpus from load balancing in cpusets
Ensure that cpus specified with the isolcpus= boot commandline option stay outside of the load balancing in the kernel scheduler. Operations like load balancing can introduce unwanted latencies, which is exactly what the isolcpus= commandline is there to prevent. Previously, simply creating a new cpuset, without even touching the cpuset.cpus field inside the new cpuset, would undo the effects of isolcpus=, by creating a scheduler domain spanning the whole system, and setting up load balancing inside that domain. The cpuset root cpuset.cpus file is read-only, so there was not even a way to undo that effect. This does not impact the majority of cpusets users, since isolcpus= is a fairly specialized feature used for realtime purposes. Cc: Peter Zijlstra <peterz@infradead.org> Cc: Clark Williams <williams@redhat.com> Cc: Li Zefan <lizefan@huawei.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Luiz Capitulino <lcapitulino@redhat.com> Cc: Mike Galbraith <umgwanakikbuti@gmail.com> Cc: cgroups@vger.kernel.org Signed-off-by: Rik van Riel <riel@redhat.com> Tested-by: David Rientjes <rientjes@google.com> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: David Rientjes <rientjes@google.com> Acked-by: Zefan Li <lizefan@huawei.com> Signed-off-by: Tejun Heo <tj@kernel.org>
This commit is contained in:
parent
3fa0818b3c
commit
47b8ea7186
|
@ -622,6 +622,7 @@ static int generate_sched_domains(cpumask_var_t **domains,
|
|||
int csn; /* how many cpuset ptrs in csa so far */
|
||||
int i, j, k; /* indices for partition finding loops */
|
||||
cpumask_var_t *doms; /* resulting partition; i.e. sched domains */
|
||||
cpumask_var_t non_isolated_cpus; /* load balanced CPUs */
|
||||
struct sched_domain_attr *dattr; /* attributes for custom domains */
|
||||
int ndoms = 0; /* number of sched domains in result */
|
||||
int nslot; /* next empty doms[] struct cpumask slot */
|
||||
|
@ -631,6 +632,10 @@ static int generate_sched_domains(cpumask_var_t **domains,
|
|||
dattr = NULL;
|
||||
csa = NULL;
|
||||
|
||||
if (!alloc_cpumask_var(&non_isolated_cpus, GFP_KERNEL))
|
||||
goto done;
|
||||
cpumask_andnot(non_isolated_cpus, cpu_possible_mask, cpu_isolated_map);
|
||||
|
||||
/* Special case for the 99% of systems with one, full, sched domain */
|
||||
if (is_sched_load_balance(&top_cpuset)) {
|
||||
ndoms = 1;
|
||||
|
@ -643,7 +648,8 @@ static int generate_sched_domains(cpumask_var_t **domains,
|
|||
*dattr = SD_ATTR_INIT;
|
||||
update_domain_attr_tree(dattr, &top_cpuset);
|
||||
}
|
||||
cpumask_copy(doms[0], top_cpuset.effective_cpus);
|
||||
cpumask_and(doms[0], top_cpuset.effective_cpus,
|
||||
non_isolated_cpus);
|
||||
|
||||
goto done;
|
||||
}
|
||||
|
@ -666,7 +672,8 @@ static int generate_sched_domains(cpumask_var_t **domains,
|
|||
* the corresponding sched domain.
|
||||
*/
|
||||
if (!cpumask_empty(cp->cpus_allowed) &&
|
||||
!is_sched_load_balance(cp))
|
||||
!(is_sched_load_balance(cp) &&
|
||||
cpumask_intersects(cp->cpus_allowed, non_isolated_cpus)))
|
||||
continue;
|
||||
|
||||
if (is_sched_load_balance(cp))
|
||||
|
@ -748,6 +755,7 @@ static int generate_sched_domains(cpumask_var_t **domains,
|
|||
|
||||
if (apn == b->pn) {
|
||||
cpumask_or(dp, dp, b->effective_cpus);
|
||||
cpumask_and(dp, dp, non_isolated_cpus);
|
||||
if (dattr)
|
||||
update_domain_attr_tree(dattr + nslot, b);
|
||||
|
||||
|
@ -760,6 +768,7 @@ static int generate_sched_domains(cpumask_var_t **domains,
|
|||
BUG_ON(nslot != ndoms);
|
||||
|
||||
done:
|
||||
free_cpumask_var(non_isolated_cpus);
|
||||
kfree(csa);
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue