mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	cpu/hotplug: Unpark smpboot threads from the state machine
Handle the smpboot threads in the state machine. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: linux-arch@vger.kernel.org Cc: Rik van Riel <riel@redhat.com> Cc: Rafael Wysocki <rafael.j.wysocki@intel.com> Cc: "Srivatsa S. Bhat" <srivatsa@mit.edu> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Arjan van de Ven <arjan@linux.intel.com> Cc: Sebastian Siewior <bigeasy@linutronix.de> Cc: Rusty Russell <rusty@rustcorp.com.au> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Tejun Heo <tj@kernel.org> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Paul McKenney <paulmck@linux.vnet.ibm.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Paul Turner <pjt@google.com> Link: http://lkml.kernel.org/r/20160226182341.295777684@linutronix.de Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
		
							parent
							
								
									949338e351
								
							
						
					
					
						commit
						931ef16330
					
				
					 6 changed files with 13 additions and 45 deletions
				
			
		|  | @ -78,7 +78,7 @@ enum { | ||||||
| 	/* migration should happen before other stuff but after perf */ | 	/* migration should happen before other stuff but after perf */ | ||||||
| 	CPU_PRI_PERF		= 20, | 	CPU_PRI_PERF		= 20, | ||||||
| 	CPU_PRI_MIGRATION	= 10, | 	CPU_PRI_MIGRATION	= 10, | ||||||
| 	CPU_PRI_SMPBOOT		= 9, | 
 | ||||||
| 	/* bring up workqueues before normal notifiers and down after */ | 	/* bring up workqueues before normal notifiers and down after */ | ||||||
| 	CPU_PRI_WORKQUEUE_UP	= 5, | 	CPU_PRI_WORKQUEUE_UP	= 5, | ||||||
| 	CPU_PRI_WORKQUEUE_DOWN	= -5, | 	CPU_PRI_WORKQUEUE_DOWN	= -5, | ||||||
|  | @ -172,7 +172,6 @@ static inline void __unregister_cpu_notifier(struct notifier_block *nb) | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| void smpboot_thread_init(void); |  | ||||||
| int cpu_up(unsigned int cpu); | int cpu_up(unsigned int cpu); | ||||||
| void notify_cpu_starting(unsigned int cpu); | void notify_cpu_starting(unsigned int cpu); | ||||||
| extern void cpu_maps_update_begin(void); | extern void cpu_maps_update_begin(void); | ||||||
|  | @ -221,10 +220,6 @@ static inline void cpu_notifier_register_done(void) | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static inline void smpboot_thread_init(void) |  | ||||||
| { |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #endif /* CONFIG_SMP */ | #endif /* CONFIG_SMP */ | ||||||
| extern struct bus_type cpu_subsys; | extern struct bus_type cpu_subsys; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -11,6 +11,7 @@ enum cpuhp_state { | ||||||
| 	CPUHP_AP_ONLINE, | 	CPUHP_AP_ONLINE, | ||||||
| 	CPUHP_TEARDOWN_CPU, | 	CPUHP_TEARDOWN_CPU, | ||||||
| 	CPUHP_CPU_SET_ACTIVE, | 	CPUHP_CPU_SET_ACTIVE, | ||||||
|  | 	CPUHP_SMPBOOT_THREADS, | ||||||
| 	CPUHP_NOTIFY_ONLINE, | 	CPUHP_NOTIFY_ONLINE, | ||||||
| 	CPUHP_ONLINE_DYN, | 	CPUHP_ONLINE_DYN, | ||||||
| 	CPUHP_ONLINE_DYN_END		= CPUHP_ONLINE_DYN + 30, | 	CPUHP_ONLINE_DYN_END		= CPUHP_ONLINE_DYN + 30, | ||||||
|  |  | ||||||
|  | @ -388,7 +388,6 @@ static noinline void __init_refok rest_init(void) | ||||||
| 	int pid; | 	int pid; | ||||||
| 
 | 
 | ||||||
| 	rcu_scheduler_starting(); | 	rcu_scheduler_starting(); | ||||||
| 	smpboot_thread_init(); |  | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * We need to spawn init first so that it obtains pid 1, however | 	 * We need to spawn init first so that it obtains pid 1, however | ||||||
| 	 * the init task will end up wanting to create kthreads, which, if | 	 * the init task will end up wanting to create kthreads, which, if | ||||||
|  |  | ||||||
							
								
								
									
										39
									
								
								kernel/cpu.c
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								kernel/cpu.c
									
									
									
									
									
								
							|  | @ -481,8 +481,6 @@ static int takedown_cpu(unsigned int cpu) | ||||||
| 	else | 	else | ||||||
| 		synchronize_rcu(); | 		synchronize_rcu(); | ||||||
| 
 | 
 | ||||||
| 	smpboot_park_threads(cpu); |  | ||||||
| 
 |  | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * Prevent irq alloc/free while the dying cpu reorganizes the | 	 * Prevent irq alloc/free while the dying cpu reorganizes the | ||||||
| 	 * interrupt affinities. | 	 * interrupt affinities. | ||||||
|  | @ -612,38 +610,6 @@ int cpu_down(unsigned int cpu) | ||||||
| EXPORT_SYMBOL(cpu_down); | EXPORT_SYMBOL(cpu_down); | ||||||
| #endif /*CONFIG_HOTPLUG_CPU*/ | #endif /*CONFIG_HOTPLUG_CPU*/ | ||||||
| 
 | 
 | ||||||
| /*
 |  | ||||||
|  * Unpark per-CPU smpboot kthreads at CPU-online time. |  | ||||||
|  */ |  | ||||||
| static int smpboot_thread_call(struct notifier_block *nfb, |  | ||||||
| 			       unsigned long action, void *hcpu) |  | ||||||
| { |  | ||||||
| 	int cpu = (long)hcpu; |  | ||||||
| 
 |  | ||||||
| 	switch (action & ~CPU_TASKS_FROZEN) { |  | ||||||
| 
 |  | ||||||
| 	case CPU_DOWN_FAILED: |  | ||||||
| 	case CPU_ONLINE: |  | ||||||
| 		smpboot_unpark_threads(cpu); |  | ||||||
| 		break; |  | ||||||
| 
 |  | ||||||
| 	default: |  | ||||||
| 		break; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return NOTIFY_OK; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static struct notifier_block smpboot_thread_notifier = { |  | ||||||
| 	.notifier_call = smpboot_thread_call, |  | ||||||
| 	.priority = CPU_PRI_SMPBOOT, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| void smpboot_thread_init(void) |  | ||||||
| { |  | ||||||
| 	register_cpu_notifier(&smpboot_thread_notifier); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /**
 | /**
 | ||||||
|  * notify_cpu_starting(cpu) - call the CPU_STARTING notifiers |  * notify_cpu_starting(cpu) - call the CPU_STARTING notifiers | ||||||
|  * @cpu: cpu that just started |  * @cpu: cpu that just started | ||||||
|  | @ -959,6 +925,11 @@ static struct cpuhp_step cpuhp_bp_states[] = { | ||||||
| 		.startup		= cpuhp_set_cpu_active, | 		.startup		= cpuhp_set_cpu_active, | ||||||
| 		.teardown		= NULL, | 		.teardown		= NULL, | ||||||
| 	}, | 	}, | ||||||
|  | 	[CPUHP_SMPBOOT_THREADS] = { | ||||||
|  | 		.name			= "smpboot:threads", | ||||||
|  | 		.startup		= smpboot_unpark_threads, | ||||||
|  | 		.teardown		= smpboot_park_threads, | ||||||
|  | 	}, | ||||||
| 	[CPUHP_NOTIFY_ONLINE] = { | 	[CPUHP_NOTIFY_ONLINE] = { | ||||||
| 		.name			= "notify:online", | 		.name			= "notify:online", | ||||||
| 		.startup		= notify_online, | 		.startup		= notify_online, | ||||||
|  |  | ||||||
|  | @ -226,7 +226,7 @@ static void smpboot_unpark_thread(struct smp_hotplug_thread *ht, unsigned int cp | ||||||
| 		kthread_unpark(tsk); | 		kthread_unpark(tsk); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void smpboot_unpark_threads(unsigned int cpu) | int smpboot_unpark_threads(unsigned int cpu) | ||||||
| { | { | ||||||
| 	struct smp_hotplug_thread *cur; | 	struct smp_hotplug_thread *cur; | ||||||
| 
 | 
 | ||||||
|  | @ -235,6 +235,7 @@ void smpboot_unpark_threads(unsigned int cpu) | ||||||
| 		if (cpumask_test_cpu(cpu, cur->cpumask)) | 		if (cpumask_test_cpu(cpu, cur->cpumask)) | ||||||
| 			smpboot_unpark_thread(cur, cpu); | 			smpboot_unpark_thread(cur, cpu); | ||||||
| 	mutex_unlock(&smpboot_threads_lock); | 	mutex_unlock(&smpboot_threads_lock); | ||||||
|  | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void smpboot_park_thread(struct smp_hotplug_thread *ht, unsigned int cpu) | static void smpboot_park_thread(struct smp_hotplug_thread *ht, unsigned int cpu) | ||||||
|  | @ -245,7 +246,7 @@ static void smpboot_park_thread(struct smp_hotplug_thread *ht, unsigned int cpu) | ||||||
| 		kthread_park(tsk); | 		kthread_park(tsk); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void smpboot_park_threads(unsigned int cpu) | int smpboot_park_threads(unsigned int cpu) | ||||||
| { | { | ||||||
| 	struct smp_hotplug_thread *cur; | 	struct smp_hotplug_thread *cur; | ||||||
| 
 | 
 | ||||||
|  | @ -253,6 +254,7 @@ void smpboot_park_threads(unsigned int cpu) | ||||||
| 	list_for_each_entry_reverse(cur, &hotplug_threads, list) | 	list_for_each_entry_reverse(cur, &hotplug_threads, list) | ||||||
| 		smpboot_park_thread(cur, cpu); | 		smpboot_park_thread(cur, cpu); | ||||||
| 	mutex_unlock(&smpboot_threads_lock); | 	mutex_unlock(&smpboot_threads_lock); | ||||||
|  | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void smpboot_destroy_threads(struct smp_hotplug_thread *ht) | static void smpboot_destroy_threads(struct smp_hotplug_thread *ht) | ||||||
|  |  | ||||||
|  | @ -14,7 +14,7 @@ static inline void idle_threads_init(void) { } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| int smpboot_create_threads(unsigned int cpu); | int smpboot_create_threads(unsigned int cpu); | ||||||
| void smpboot_park_threads(unsigned int cpu); | int smpboot_park_threads(unsigned int cpu); | ||||||
| void smpboot_unpark_threads(unsigned int cpu); | int smpboot_unpark_threads(unsigned int cpu); | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Thomas Gleixner
						Thomas Gleixner