mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-09-04 20:19:47 +08:00 
			
		
		
		
	 325ea10c08
			
		
	
	
		325ea10c08
		
	
	
	
	
		
			
			Do the following cleanups and simplifications: - sched/sched.h already includes <asm/paravirt.h>, so no need to include it in sched/core.c again. - order the <linux/sched/*.h> headers alphabetically - add all <linux/sched/*.h> headers to kernel/sched/sched.h - remove all unnecessary includes from the .c files that are already included in kernel/sched/sched.h. Finally, make all scheduler .c files use a single common header: #include "sched.h" ... which now contains a union of the relied upon headers. This makes the various .c files easier to read and easier to handle. 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>
		
			
				
	
	
		
			154 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			154 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  *  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
 | |
|  * Copyright (C) 2017-2018 SUSE, Frederic Weisbecker
 | |
|  *
 | |
|  */
 | |
| #include "sched.h"
 | |
| 
 | |
| DEFINE_STATIC_KEY_FALSE(housekeeping_overriden);
 | |
| EXPORT_SYMBOL_GPL(housekeeping_overriden);
 | |
| static cpumask_var_t housekeeping_mask;
 | |
| static unsigned int housekeeping_flags;
 | |
| 
 | |
| int housekeeping_any_cpu(enum hk_flags flags)
 | |
| {
 | |
| 	if (static_branch_unlikely(&housekeeping_overriden))
 | |
| 		if (housekeeping_flags & flags)
 | |
| 			return cpumask_any_and(housekeeping_mask, cpu_online_mask);
 | |
| 	return smp_processor_id();
 | |
| }
 | |
| EXPORT_SYMBOL_GPL(housekeeping_any_cpu);
 | |
| 
 | |
| const struct cpumask *housekeeping_cpumask(enum hk_flags flags)
 | |
| {
 | |
| 	if (static_branch_unlikely(&housekeeping_overriden))
 | |
| 		if (housekeeping_flags & flags)
 | |
| 			return housekeeping_mask;
 | |
| 	return cpu_possible_mask;
 | |
| }
 | |
| EXPORT_SYMBOL_GPL(housekeeping_cpumask);
 | |
| 
 | |
| void housekeeping_affine(struct task_struct *t, enum hk_flags flags)
 | |
| {
 | |
| 	if (static_branch_unlikely(&housekeeping_overriden))
 | |
| 		if (housekeeping_flags & flags)
 | |
| 			set_cpus_allowed_ptr(t, housekeeping_mask);
 | |
| }
 | |
| EXPORT_SYMBOL_GPL(housekeeping_affine);
 | |
| 
 | |
| bool housekeeping_test_cpu(int cpu, enum hk_flags flags)
 | |
| {
 | |
| 	if (static_branch_unlikely(&housekeeping_overriden))
 | |
| 		if (housekeeping_flags & flags)
 | |
| 			return cpumask_test_cpu(cpu, housekeeping_mask);
 | |
| 	return true;
 | |
| }
 | |
| EXPORT_SYMBOL_GPL(housekeeping_test_cpu);
 | |
| 
 | |
| void __init housekeeping_init(void)
 | |
| {
 | |
| 	if (!housekeeping_flags)
 | |
| 		return;
 | |
| 
 | |
| 	static_branch_enable(&housekeeping_overriden);
 | |
| 
 | |
| 	if (housekeeping_flags & HK_FLAG_TICK)
 | |
| 		sched_tick_offload_init();
 | |
| 
 | |
| 	/* We need at least one CPU to handle housekeeping work */
 | |
| 	WARN_ON_ONCE(cpumask_empty(housekeeping_mask));
 | |
| }
 | |
| 
 | |
| static int __init housekeeping_setup(char *str, enum hk_flags flags)
 | |
| {
 | |
| 	cpumask_var_t non_housekeeping_mask;
 | |
| 	int err;
 | |
| 
 | |
| 	alloc_bootmem_cpumask_var(&non_housekeeping_mask);
 | |
| 	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");
 | |
| 		free_bootmem_cpumask_var(non_housekeeping_mask);
 | |
| 		return 0;
 | |
| 	}
 | |
| 
 | |
| 	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);
 | |
| 	}
 | |
| 
 | |
| 	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;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	housekeeping_flags |= flags;
 | |
| 
 | |
| 	free_bootmem_cpumask_var(non_housekeeping_mask);
 | |
| 
 | |
| 	return 1;
 | |
| }
 | |
| 
 | |
| static int __init housekeeping_nohz_full_setup(char *str)
 | |
| {
 | |
| 	unsigned int flags;
 | |
| 
 | |
| 	flags = HK_FLAG_TICK | HK_FLAG_WQ | HK_FLAG_TIMER | HK_FLAG_RCU | HK_FLAG_MISC;
 | |
| 
 | |
| 	return housekeeping_setup(str, flags);
 | |
| }
 | |
| __setup("nohz_full=", housekeeping_nohz_full_setup);
 | |
| 
 | |
| static int __init housekeeping_isolcpus_setup(char *str)
 | |
| {
 | |
| 	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);
 | |
| }
 | |
| __setup("isolcpus=", housekeeping_isolcpus_setup);
 |