2017-10-27 02:42:28 +00:00
|
|
|
/*
|
|
|
|
* Housekeeping management. Manage the targets for routine code that can run on
|
|
|
|
* any CPU: unbound workqueues, timers, kthreads and any offloadable work.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2017 Red Hat, Inc., Frederic Weisbecker
|
2018-02-21 04:17:26 +00:00
|
|
|
* Copyright (C) 2017-2018 SUSE, Frederic Weisbecker
|
2017-10-27 02:42:28 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
#include <linux/sched/isolation.h>
|
|
|
|
#include <linux/tick.h>
|
|
|
|
#include <linux/init.h>
|
|
|
|
#include <linux/kernel.h>
|
2017-10-27 02:42:32 +00:00
|
|
|
#include <linux/static_key.h>
|
2017-10-27 02:42:38 +00:00
|
|
|
#include <linux/ctype.h>
|
sched: Clean up and harmonize the coding style of the scheduler code base
A good number of small style inconsistencies have accumulated
in the scheduler core, so do a pass over them to harmonize
all these details:
- fix speling in comments,
- use curly braces for multi-line statements,
- remove unnecessary parentheses from integer literals,
- capitalize consistently,
- remove stray newlines,
- add comments where necessary,
- remove invalid/unnecessary comments,
- align structure definitions and other data types vertically,
- add missing newlines for increased readability,
- fix vertical tabulation where it's misaligned,
- harmonize preprocessor conditional block labeling
and vertical alignment,
- remove line-breaks where they uglify the code,
- add newline after local variable definitions,
No change in functionality:
md5:
1191fa0a890cfa8132156d2959d7e9e2 built-in.o.before.asm
1191fa0a890cfa8132156d2959d7e9e2 built-in.o.after.asm
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
2018-03-03 13:01:12 +00:00
|
|
|
|
2018-02-21 04:17:27 +00:00
|
|
|
#include "sched.h"
|
2017-10-27 02:42:28 +00:00
|
|
|
|
2017-10-27 02:42:32 +00:00
|
|
|
DEFINE_STATIC_KEY_FALSE(housekeeping_overriden);
|
|
|
|
EXPORT_SYMBOL_GPL(housekeeping_overriden);
|
2017-10-27 02:42:31 +00:00
|
|
|
static cpumask_var_t housekeeping_mask;
|
2017-10-27 02:42:35 +00:00
|
|
|
static unsigned int housekeeping_flags;
|
2017-10-27 02:42:31 +00:00
|
|
|
|
2017-10-27 02:42:35 +00:00
|
|
|
int housekeeping_any_cpu(enum hk_flags flags)
|
2017-10-27 02:42:31 +00:00
|
|
|
{
|
2017-10-27 02:42:32 +00:00
|
|
|
if (static_branch_unlikely(&housekeeping_overriden))
|
2017-10-27 02:42:35 +00:00
|
|
|
if (housekeeping_flags & flags)
|
|
|
|
return cpumask_any_and(housekeeping_mask, cpu_online_mask);
|
2017-10-27 02:42:31 +00:00
|
|
|
return smp_processor_id();
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(housekeeping_any_cpu);
|
|
|
|
|
2017-10-27 02:42:35 +00:00
|
|
|
const struct cpumask *housekeeping_cpumask(enum hk_flags flags)
|
2017-10-27 02:42:31 +00:00
|
|
|
{
|
2017-10-27 02:42:32 +00:00
|
|
|
if (static_branch_unlikely(&housekeeping_overriden))
|
2017-10-27 02:42:35 +00:00
|
|
|
if (housekeeping_flags & flags)
|
|
|
|
return housekeeping_mask;
|
2017-10-27 02:42:31 +00:00
|
|
|
return cpu_possible_mask;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(housekeeping_cpumask);
|
|
|
|
|
2017-10-27 02:42:35 +00:00
|
|
|
void housekeeping_affine(struct task_struct *t, enum hk_flags flags)
|
2017-10-27 02:42:31 +00:00
|
|
|
{
|
2017-10-27 02:42:32 +00:00
|
|
|
if (static_branch_unlikely(&housekeeping_overriden))
|
2017-10-27 02:42:35 +00:00
|
|
|
if (housekeeping_flags & flags)
|
|
|
|
set_cpus_allowed_ptr(t, housekeeping_mask);
|
2017-10-27 02:42:31 +00:00
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(housekeeping_affine);
|
|
|
|
|
2017-10-27 02:42:35 +00:00
|
|
|
bool housekeeping_test_cpu(int cpu, enum hk_flags flags)
|
2017-10-27 02:42:31 +00:00
|
|
|
{
|
2017-10-27 02:42:32 +00:00
|
|
|
if (static_branch_unlikely(&housekeeping_overriden))
|
2017-10-27 02:42:35 +00:00
|
|
|
if (housekeeping_flags & flags)
|
|
|
|
return cpumask_test_cpu(cpu, housekeeping_mask);
|
2017-10-27 02:42:31 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(housekeeping_test_cpu);
|
2017-10-27 02:42:28 +00:00
|
|
|
|
|
|
|
void __init housekeeping_init(void)
|
|
|
|
{
|
2017-10-27 02:42:36 +00:00
|
|
|
if (!housekeeping_flags)
|
2017-10-27 02:42:28 +00:00
|
|
|
return;
|
|
|
|
|
2017-10-27 02:42:36 +00:00
|
|
|
static_branch_enable(&housekeeping_overriden);
|
|
|
|
|
2018-02-21 04:17:27 +00:00
|
|
|
if (housekeeping_flags & HK_FLAG_TICK)
|
|
|
|
sched_tick_offload_init();
|
|
|
|
|
2017-10-27 02:42:36 +00:00
|
|
|
/* We need at least one CPU to handle housekeeping work */
|
|
|
|
WARN_ON_ONCE(cpumask_empty(housekeeping_mask));
|
|
|
|
}
|
|
|
|
|
2017-10-27 02:42:37 +00:00
|
|
|
static int __init housekeeping_setup(char *str, enum hk_flags flags)
|
2017-10-27 02:42:36 +00:00
|
|
|
{
|
|
|
|
cpumask_var_t non_housekeeping_mask;
|
2017-10-27 02:42:37 +00:00
|
|
|
int err;
|
2017-10-27 02:42:36 +00:00
|
|
|
|
|
|
|
alloc_bootmem_cpumask_var(&non_housekeeping_mask);
|
2017-10-27 02:42:37 +00:00
|
|
|
err = cpulist_parse(str, non_housekeeping_mask);
|
|
|
|
if (err < 0 || cpumask_last(non_housekeeping_mask) >= nr_cpu_ids) {
|
|
|
|
pr_warn("Housekeeping: nohz_full= or isolcpus= incorrect CPU range\n");
|
2017-10-27 02:42:36 +00:00
|
|
|
free_bootmem_cpumask_var(non_housekeeping_mask);
|
|
|
|
return 0;
|
2017-10-27 02:42:28 +00:00
|
|
|
}
|
|
|
|
|
2017-10-27 02:42:37 +00:00
|
|
|
if (!housekeeping_flags) {
|
|
|
|
alloc_bootmem_cpumask_var(&housekeeping_mask);
|
|
|
|
cpumask_andnot(housekeeping_mask,
|
|
|
|
cpu_possible_mask, non_housekeeping_mask);
|
|
|
|
if (cpumask_empty(housekeeping_mask))
|
|
|
|
cpumask_set_cpu(smp_processor_id(), housekeeping_mask);
|
|
|
|
} else {
|
|
|
|
cpumask_var_t tmp;
|
|
|
|
|
|
|
|
alloc_bootmem_cpumask_var(&tmp);
|
|
|
|
cpumask_andnot(tmp, cpu_possible_mask, non_housekeeping_mask);
|
|
|
|
if (!cpumask_equal(tmp, housekeeping_mask)) {
|
|
|
|
pr_warn("Housekeeping: nohz_full= must match isolcpus=\n");
|
|
|
|
free_bootmem_cpumask_var(tmp);
|
|
|
|
free_bootmem_cpumask_var(non_housekeeping_mask);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
free_bootmem_cpumask_var(tmp);
|
|
|
|
}
|
2017-10-27 02:42:35 +00:00
|
|
|
|
2017-10-27 02:42:37 +00:00
|
|
|
if ((flags & HK_FLAG_TICK) && !(housekeeping_flags & HK_FLAG_TICK)) {
|
|
|
|
if (IS_ENABLED(CONFIG_NO_HZ_FULL)) {
|
|
|
|
tick_nohz_full_setup(non_housekeeping_mask);
|
|
|
|
} else {
|
|
|
|
pr_warn("Housekeeping: nohz unsupported."
|
|
|
|
" Build with CONFIG_NO_HZ_FULL\n");
|
|
|
|
free_bootmem_cpumask_var(non_housekeeping_mask);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2017-10-27 02:42:32 +00:00
|
|
|
|
2017-10-27 02:42:37 +00:00
|
|
|
housekeeping_flags |= flags;
|
2017-10-27 02:42:36 +00:00
|
|
|
|
|
|
|
free_bootmem_cpumask_var(non_housekeeping_mask);
|
|
|
|
|
|
|
|
return 1;
|
2017-10-27 02:42:28 +00:00
|
|
|
}
|
2017-10-27 02:42:37 +00:00
|
|
|
|
|
|
|
static int __init housekeeping_nohz_full_setup(char *str)
|
|
|
|
{
|
|
|
|
unsigned int flags;
|
|
|
|
|
2018-02-21 04:17:26 +00:00
|
|
|
flags = HK_FLAG_TICK | HK_FLAG_WQ | HK_FLAG_TIMER | HK_FLAG_RCU | HK_FLAG_MISC;
|
2017-10-27 02:42:37 +00:00
|
|
|
|
|
|
|
return housekeeping_setup(str, flags);
|
|
|
|
}
|
2017-10-27 02:42:36 +00:00
|
|
|
__setup("nohz_full=", housekeeping_nohz_full_setup);
|
2017-10-27 02:42:37 +00:00
|
|
|
|
|
|
|
static int __init housekeeping_isolcpus_setup(char *str)
|
|
|
|
{
|
2017-10-27 02:42:38 +00:00
|
|
|
unsigned int flags = 0;
|
|
|
|
|
|
|
|
while (isalpha(*str)) {
|
|
|
|
if (!strncmp(str, "nohz,", 5)) {
|
|
|
|
str += 5;
|
|
|
|
flags |= HK_FLAG_TICK;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!strncmp(str, "domain,", 7)) {
|
|
|
|
str += 7;
|
|
|
|
flags |= HK_FLAG_DOMAIN;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
pr_warn("isolcpus: Error, unknown flag\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Default behaviour for isolcpus without flags */
|
|
|
|
if (!flags)
|
|
|
|
flags |= HK_FLAG_DOMAIN;
|
|
|
|
|
|
|
|
return housekeeping_setup(str, flags);
|
2017-10-27 02:42:37 +00:00
|
|
|
}
|
|
|
|
__setup("isolcpus=", housekeeping_isolcpus_setup);
|