Skip to content

Commit edb9382

Browse files
Frederic WeisbeckerIngo Molnar
authored andcommitted
sched/isolation: Move isolcpus= handling to the housekeeping code
We want to centralize the isolation features, to be done by the housekeeping subsystem and scheduler domain isolation is a significant part of it. No intended behaviour change, we just reuse the housekeeping cpumask and core code. Signed-off-by: Frederic Weisbecker <[email protected]> Acked-by: Thomas Gleixner <[email protected]> Cc: Chris Metcalf <[email protected]> Cc: Christoph Lameter <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Luiz Capitulino <[email protected]> Cc: Mike Galbraith <[email protected]> Cc: Paul E. McKenney <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Rik van Riel <[email protected]> Cc: Wanpeng Li <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Ingo Molnar <[email protected]>
1 parent 6f1982f commit edb9382

File tree

7 files changed

+73
-59
lines changed

7 files changed

+73
-59
lines changed

drivers/base/cpu.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <linux/cpufeature.h>
1919
#include <linux/tick.h>
2020
#include <linux/pm_qos.h>
21+
#include <linux/sched/isolation.h>
2122

2223
#include "base.h"
2324

@@ -271,8 +272,16 @@ static ssize_t print_cpus_isolated(struct device *dev,
271272
struct device_attribute *attr, char *buf)
272273
{
273274
int n = 0, len = PAGE_SIZE-2;
275+
cpumask_var_t isolated;
274276

275-
n = scnprintf(buf, len, "%*pbl\n", cpumask_pr_args(cpu_isolated_map));
277+
if (!alloc_cpumask_var(&isolated, GFP_KERNEL))
278+
return -ENOMEM;
279+
280+
cpumask_andnot(isolated, cpu_possible_mask,
281+
housekeeping_cpumask(HK_FLAG_DOMAIN));
282+
n = scnprintf(buf, len, "%*pbl\n", cpumask_pr_args(isolated));
283+
284+
free_cpumask_var(isolated);
276285

277286
return n;
278287
}

include/linux/sched.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,6 @@ struct task_group;
165165
/* Task command name length: */
166166
#define TASK_COMM_LEN 16
167167

168-
extern cpumask_var_t cpu_isolated_map;
169-
170168
extern void scheduler_tick(void);
171169

172170
#define MAX_SCHEDULE_TIMEOUT LONG_MAX

include/linux/sched/isolation.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ enum hk_flags {
1111
HK_FLAG_MISC = (1 << 2),
1212
HK_FLAG_SCHED = (1 << 3),
1313
HK_FLAG_TICK = (1 << 4),
14+
HK_FLAG_DOMAIN = (1 << 5),
1415
};
1516

1617
#ifdef CONFIG_CPU_ISOLATION

kernel/cgroup/cpuset.c

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
#include <linux/backing-dev.h>
5858
#include <linux/sort.h>
5959
#include <linux/oom.h>
60-
60+
#include <linux/sched/isolation.h>
6161
#include <linux/uaccess.h>
6262
#include <linux/atomic.h>
6363
#include <linux/mutex.h>
@@ -656,7 +656,6 @@ static int generate_sched_domains(cpumask_var_t **domains,
656656
int csn; /* how many cpuset ptrs in csa so far */
657657
int i, j, k; /* indices for partition finding loops */
658658
cpumask_var_t *doms; /* resulting partition; i.e. sched domains */
659-
cpumask_var_t non_isolated_cpus; /* load balanced CPUs */
660659
struct sched_domain_attr *dattr; /* attributes for custom domains */
661660
int ndoms = 0; /* number of sched domains in result */
662661
int nslot; /* next empty doms[] struct cpumask slot */
@@ -666,10 +665,6 @@ static int generate_sched_domains(cpumask_var_t **domains,
666665
dattr = NULL;
667666
csa = NULL;
668667

669-
if (!alloc_cpumask_var(&non_isolated_cpus, GFP_KERNEL))
670-
goto done;
671-
cpumask_andnot(non_isolated_cpus, cpu_possible_mask, cpu_isolated_map);
672-
673668
/* Special case for the 99% of systems with one, full, sched domain */
674669
if (is_sched_load_balance(&top_cpuset)) {
675670
ndoms = 1;
@@ -683,7 +678,7 @@ static int generate_sched_domains(cpumask_var_t **domains,
683678
update_domain_attr_tree(dattr, &top_cpuset);
684679
}
685680
cpumask_and(doms[0], top_cpuset.effective_cpus,
686-
non_isolated_cpus);
681+
housekeeping_cpumask(HK_FLAG_DOMAIN));
687682

688683
goto done;
689684
}
@@ -707,7 +702,8 @@ static int generate_sched_domains(cpumask_var_t **domains,
707702
*/
708703
if (!cpumask_empty(cp->cpus_allowed) &&
709704
!(is_sched_load_balance(cp) &&
710-
cpumask_intersects(cp->cpus_allowed, non_isolated_cpus)))
705+
cpumask_intersects(cp->cpus_allowed,
706+
housekeeping_cpumask(HK_FLAG_DOMAIN))))
711707
continue;
712708

713709
if (is_sched_load_balance(cp))
@@ -789,7 +785,7 @@ static int generate_sched_domains(cpumask_var_t **domains,
789785

790786
if (apn == b->pn) {
791787
cpumask_or(dp, dp, b->effective_cpus);
792-
cpumask_and(dp, dp, non_isolated_cpus);
788+
cpumask_and(dp, dp, housekeeping_cpumask(HK_FLAG_DOMAIN));
793789
if (dattr)
794790
update_domain_attr_tree(dattr + nslot, b);
795791

@@ -802,7 +798,6 @@ static int generate_sched_domains(cpumask_var_t **domains,
802798
BUG_ON(nslot != ndoms);
803799

804800
done:
805-
free_cpumask_var(non_isolated_cpus);
806801
kfree(csa);
807802

808803
/*

kernel/sched/core.c

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,6 @@ __read_mostly int scheduler_running;
8484
*/
8585
int sysctl_sched_rt_runtime = 950000;
8686

87-
/* CPUs with isolated domains */
88-
cpumask_var_t cpu_isolated_map;
89-
9087
/*
9188
* __task_rq_lock - lock the rq @p resides on.
9289
*/
@@ -5735,10 +5732,6 @@ static inline void sched_init_smt(void) { }
57355732

57365733
void __init sched_init_smp(void)
57375734
{
5738-
cpumask_var_t non_isolated_cpus;
5739-
5740-
alloc_cpumask_var(&non_isolated_cpus, GFP_KERNEL);
5741-
57425735
sched_init_numa();
57435736

57445737
/*
@@ -5748,16 +5741,12 @@ void __init sched_init_smp(void)
57485741
*/
57495742
mutex_lock(&sched_domains_mutex);
57505743
sched_init_domains(cpu_active_mask);
5751-
cpumask_andnot(non_isolated_cpus, cpu_possible_mask, cpu_isolated_map);
5752-
if (cpumask_empty(non_isolated_cpus))
5753-
cpumask_set_cpu(smp_processor_id(), non_isolated_cpus);
57545744
mutex_unlock(&sched_domains_mutex);
57555745

57565746
/* Move init over to a non-isolated CPU */
5757-
if (set_cpus_allowed_ptr(current, non_isolated_cpus) < 0)
5747+
if (set_cpus_allowed_ptr(current, housekeeping_cpumask(HK_FLAG_DOMAIN)) < 0)
57585748
BUG();
57595749
sched_init_granularity();
5760-
free_cpumask_var(non_isolated_cpus);
57615750

57625751
init_sched_rt_class();
57635752
init_sched_dl_class();
@@ -5961,9 +5950,6 @@ void __init sched_init(void)
59615950
calc_load_update = jiffies + LOAD_FREQ;
59625951

59635952
#ifdef CONFIG_SMP
5964-
/* May be allocated at isolcpus cmdline parse time */
5965-
if (cpu_isolated_map == NULL)
5966-
zalloc_cpumask_var(&cpu_isolated_map, GFP_NOWAIT);
59675953
idle_thread_set_boot_cpu();
59685954
set_cpu_rq_start_time(smp_processor_id());
59695955
#endif

kernel/sched/isolation.c

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -63,32 +63,69 @@ void __init housekeeping_init(void)
6363
WARN_ON_ONCE(cpumask_empty(housekeeping_mask));
6464
}
6565

66-
#ifdef CONFIG_NO_HZ_FULL
67-
static int __init housekeeping_nohz_full_setup(char *str)
66+
static int __init housekeeping_setup(char *str, enum hk_flags flags)
6867
{
6968
cpumask_var_t non_housekeeping_mask;
69+
int err;
7070

7171
alloc_bootmem_cpumask_var(&non_housekeeping_mask);
72-
if (cpulist_parse(str, non_housekeeping_mask) < 0) {
73-
pr_warn("Housekeeping: Incorrect nohz_full cpumask\n");
72+
err = cpulist_parse(str, non_housekeeping_mask);
73+
if (err < 0 || cpumask_last(non_housekeeping_mask) >= nr_cpu_ids) {
74+
pr_warn("Housekeeping: nohz_full= or isolcpus= incorrect CPU range\n");
7475
free_bootmem_cpumask_var(non_housekeeping_mask);
7576
return 0;
7677
}
7778

78-
alloc_bootmem_cpumask_var(&housekeeping_mask);
79-
cpumask_andnot(housekeeping_mask, cpu_possible_mask, non_housekeeping_mask);
80-
81-
if (cpumask_empty(housekeeping_mask))
82-
cpumask_set_cpu(smp_processor_id(), housekeeping_mask);
79+
if (!housekeeping_flags) {
80+
alloc_bootmem_cpumask_var(&housekeeping_mask);
81+
cpumask_andnot(housekeeping_mask,
82+
cpu_possible_mask, non_housekeeping_mask);
83+
if (cpumask_empty(housekeeping_mask))
84+
cpumask_set_cpu(smp_processor_id(), housekeeping_mask);
85+
} else {
86+
cpumask_var_t tmp;
87+
88+
alloc_bootmem_cpumask_var(&tmp);
89+
cpumask_andnot(tmp, cpu_possible_mask, non_housekeeping_mask);
90+
if (!cpumask_equal(tmp, housekeeping_mask)) {
91+
pr_warn("Housekeeping: nohz_full= must match isolcpus=\n");
92+
free_bootmem_cpumask_var(tmp);
93+
free_bootmem_cpumask_var(non_housekeeping_mask);
94+
return 0;
95+
}
96+
free_bootmem_cpumask_var(tmp);
97+
}
8398

84-
housekeeping_flags = HK_FLAG_TICK | HK_FLAG_TIMER |
85-
HK_FLAG_RCU | HK_FLAG_MISC;
99+
if ((flags & HK_FLAG_TICK) && !(housekeeping_flags & HK_FLAG_TICK)) {
100+
if (IS_ENABLED(CONFIG_NO_HZ_FULL)) {
101+
tick_nohz_full_setup(non_housekeeping_mask);
102+
} else {
103+
pr_warn("Housekeeping: nohz unsupported."
104+
" Build with CONFIG_NO_HZ_FULL\n");
105+
free_bootmem_cpumask_var(non_housekeeping_mask);
106+
return 0;
107+
}
108+
}
86109

87-
tick_nohz_full_setup(non_housekeeping_mask);
110+
housekeeping_flags |= flags;
88111

89112
free_bootmem_cpumask_var(non_housekeeping_mask);
90113

91114
return 1;
92115
}
116+
117+
static int __init housekeeping_nohz_full_setup(char *str)
118+
{
119+
unsigned int flags;
120+
121+
flags = HK_FLAG_TICK | HK_FLAG_TIMER | HK_FLAG_RCU | HK_FLAG_MISC;
122+
123+
return housekeeping_setup(str, flags);
124+
}
93125
__setup("nohz_full=", housekeeping_nohz_full_setup);
94-
#endif
126+
127+
static int __init housekeeping_isolcpus_setup(char *str)
128+
{
129+
return housekeeping_setup(str, HK_FLAG_DOMAIN);
130+
}
131+
__setup("isolcpus=", housekeeping_isolcpus_setup);

kernel/sched/topology.c

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*/
44
#include <linux/sched.h>
55
#include <linux/mutex.h>
6+
#include <linux/sched/isolation.h>
67

78
#include "sched.h"
89

@@ -469,21 +470,6 @@ cpu_attach_domain(struct sched_domain *sd, struct root_domain *rd, int cpu)
469470
update_top_cache_domain(cpu);
470471
}
471472

472-
/* Setup the mask of CPUs configured for isolated domains */
473-
static int __init isolated_cpu_setup(char *str)
474-
{
475-
int ret;
476-
477-
alloc_bootmem_cpumask_var(&cpu_isolated_map);
478-
ret = cpulist_parse(str, cpu_isolated_map);
479-
if (ret || cpumask_last(cpu_isolated_map) >= nr_cpu_ids) {
480-
pr_err("sched: Error, all isolcpus= values must be between 0 and %u - ignoring them.\n", nr_cpu_ids-1);
481-
return 0;
482-
}
483-
return 1;
484-
}
485-
__setup("isolcpus=", isolated_cpu_setup);
486-
487473
struct s_data {
488474
struct sched_domain ** __percpu sd;
489475
struct root_domain *rd;
@@ -1792,7 +1778,7 @@ int sched_init_domains(const struct cpumask *cpu_map)
17921778
doms_cur = alloc_sched_domains(ndoms_cur);
17931779
if (!doms_cur)
17941780
doms_cur = &fallback_doms;
1795-
cpumask_andnot(doms_cur[0], cpu_map, cpu_isolated_map);
1781+
cpumask_and(doms_cur[0], cpu_map, housekeeping_cpumask(HK_FLAG_DOMAIN));
17961782
err = build_sched_domains(doms_cur[0], NULL);
17971783
register_sched_domain_sysctl();
17981784

@@ -1875,7 +1861,8 @@ void partition_sched_domains(int ndoms_new, cpumask_var_t doms_new[],
18751861
doms_new = alloc_sched_domains(1);
18761862
if (doms_new) {
18771863
n = 1;
1878-
cpumask_andnot(doms_new[0], cpu_active_mask, cpu_isolated_map);
1864+
cpumask_and(doms_new[0], cpu_active_mask,
1865+
housekeeping_cpumask(HK_FLAG_DOMAIN));
18791866
}
18801867
} else {
18811868
n = ndoms_new;
@@ -1898,7 +1885,8 @@ void partition_sched_domains(int ndoms_new, cpumask_var_t doms_new[],
18981885
if (!doms_new) {
18991886
n = 0;
19001887
doms_new = &fallback_doms;
1901-
cpumask_andnot(doms_new[0], cpu_active_mask, cpu_isolated_map);
1888+
cpumask_and(doms_new[0], cpu_active_mask,
1889+
housekeeping_cpumask(HK_FLAG_DOMAIN));
19021890
}
19031891

19041892
/* Build new domains: */

0 commit comments

Comments
 (0)