Skip to content

Commit 47b8ea7

Browse files
Rik van Rielhtejun
authored andcommitted
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 <[email protected]> Cc: Clark Williams <[email protected]> Cc: Li Zefan <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Luiz Capitulino <[email protected]> Cc: Mike Galbraith <[email protected]> Cc: [email protected] Signed-off-by: Rik van Riel <[email protected]> Tested-by: David Rientjes <[email protected]> Acked-by: Peter Zijlstra (Intel) <[email protected]> Acked-by: David Rientjes <[email protected]> Acked-by: Zefan Li <[email protected]> Signed-off-by: Tejun Heo <[email protected]>
1 parent 3fa0818 commit 47b8ea7

File tree

1 file changed

+11
-2
lines changed

1 file changed

+11
-2
lines changed

kernel/cpuset.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,7 @@ static int generate_sched_domains(cpumask_var_t **domains,
622622
int csn; /* how many cpuset ptrs in csa so far */
623623
int i, j, k; /* indices for partition finding loops */
624624
cpumask_var_t *doms; /* resulting partition; i.e. sched domains */
625+
cpumask_var_t non_isolated_cpus; /* load balanced CPUs */
625626
struct sched_domain_attr *dattr; /* attributes for custom domains */
626627
int ndoms = 0; /* number of sched domains in result */
627628
int nslot; /* next empty doms[] struct cpumask slot */
@@ -631,6 +632,10 @@ static int generate_sched_domains(cpumask_var_t **domains,
631632
dattr = NULL;
632633
csa = NULL;
633634

635+
if (!alloc_cpumask_var(&non_isolated_cpus, GFP_KERNEL))
636+
goto done;
637+
cpumask_andnot(non_isolated_cpus, cpu_possible_mask, cpu_isolated_map);
638+
634639
/* Special case for the 99% of systems with one, full, sched domain */
635640
if (is_sched_load_balance(&top_cpuset)) {
636641
ndoms = 1;
@@ -643,7 +648,8 @@ static int generate_sched_domains(cpumask_var_t **domains,
643648
*dattr = SD_ATTR_INIT;
644649
update_domain_attr_tree(dattr, &top_cpuset);
645650
}
646-
cpumask_copy(doms[0], top_cpuset.effective_cpus);
651+
cpumask_and(doms[0], top_cpuset.effective_cpus,
652+
non_isolated_cpus);
647653

648654
goto done;
649655
}
@@ -666,7 +672,8 @@ static int generate_sched_domains(cpumask_var_t **domains,
666672
* the corresponding sched domain.
667673
*/
668674
if (!cpumask_empty(cp->cpus_allowed) &&
669-
!is_sched_load_balance(cp))
675+
!(is_sched_load_balance(cp) &&
676+
cpumask_intersects(cp->cpus_allowed, non_isolated_cpus)))
670677
continue;
671678

672679
if (is_sched_load_balance(cp))
@@ -748,6 +755,7 @@ static int generate_sched_domains(cpumask_var_t **domains,
748755

749756
if (apn == b->pn) {
750757
cpumask_or(dp, dp, b->effective_cpus);
758+
cpumask_and(dp, dp, non_isolated_cpus);
751759
if (dattr)
752760
update_domain_attr_tree(dattr + nslot, b);
753761

@@ -760,6 +768,7 @@ static int generate_sched_domains(cpumask_var_t **domains,
760768
BUG_ON(nslot != ndoms);
761769

762770
done:
771+
free_cpumask_var(non_isolated_cpus);
763772
kfree(csa);
764773

765774
/*

0 commit comments

Comments
 (0)