mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	smp: Add new wake_up_all_idle_cpus() function
Currently kick_all_cpus_sync() can break non-polling idle cpus thru IPI interrupts. But sometimes we need to break the polling idle cpus immediately to reselect the suitable c-state, also for non-idle cpus, we need to do nothing if we try to wake up them. Here adding one new function wake_up_all_idle_cpus() to let all cpus out of idle based on function wake_up_if_idle(). Signed-off-by: Chuansheng Liu <chuansheng.liu@intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: daniel.lezcano@linaro.org Cc: rjw@rjwysocki.net Cc: linux-pm@vger.kernel.org Cc: changcheng.liu@intel.com Cc: xiaoming.wang@intel.com Cc: souvik.k.chakravarty@intel.com Cc: luto@amacapital.net Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Christoph Hellwig <hch@infradead.org> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Geert Uytterhoeven <geert+renesas@glider.be> Cc: Jan Kara <jack@suse.cz> Cc: Jens Axboe <axboe@fb.com> Cc: Jens Axboe <axboe@kernel.dk> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Michal Hocko <mhocko@suse.cz> Cc: Paul Gortmaker <paul.gortmaker@windriver.com> Cc: Roman Gushchin <klamm@yandex-team.ru> Cc: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com> Link: http://lkml.kernel.org/r/1409815075-4180-2-git-send-email-chuansheng.liu@intel.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
		
							parent
							
								
									f6be8af1c9
								
							
						
					
					
						commit
						c6f4459fc3
					
				
					 2 changed files with 24 additions and 0 deletions
				
			
		| 
						 | 
					@ -100,6 +100,7 @@ int smp_call_function_any(const struct cpumask *mask,
 | 
				
			||||||
			  smp_call_func_t func, void *info, int wait);
 | 
								  smp_call_func_t func, void *info, int wait);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void kick_all_cpus_sync(void);
 | 
					void kick_all_cpus_sync(void);
 | 
				
			||||||
 | 
					void wake_up_all_idle_cpus(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Generic and arch helpers
 | 
					 * Generic and arch helpers
 | 
				
			||||||
| 
						 | 
					@ -148,6 +149,7 @@ smp_call_function_any(const struct cpumask *mask, smp_call_func_t func,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void kick_all_cpus_sync(void) {  }
 | 
					static inline void kick_all_cpus_sync(void) {  }
 | 
				
			||||||
 | 
					static inline void wake_up_all_idle_cpus(void) {  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* !SMP */
 | 
					#endif /* !SMP */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										22
									
								
								kernel/smp.c
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								kernel/smp.c
									
									
									
									
									
								
							| 
						 | 
					@ -13,6 +13,7 @@
 | 
				
			||||||
#include <linux/gfp.h>
 | 
					#include <linux/gfp.h>
 | 
				
			||||||
#include <linux/smp.h>
 | 
					#include <linux/smp.h>
 | 
				
			||||||
#include <linux/cpu.h>
 | 
					#include <linux/cpu.h>
 | 
				
			||||||
 | 
					#include <linux/sched.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "smpboot.h"
 | 
					#include "smpboot.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -699,3 +700,24 @@ void kick_all_cpus_sync(void)
 | 
				
			||||||
	smp_call_function(do_nothing, NULL, 1);
 | 
						smp_call_function(do_nothing, NULL, 1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(kick_all_cpus_sync);
 | 
					EXPORT_SYMBOL_GPL(kick_all_cpus_sync);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * wake_up_all_idle_cpus - break all cpus out of idle
 | 
				
			||||||
 | 
					 * wake_up_all_idle_cpus try to break all cpus which is in idle state even
 | 
				
			||||||
 | 
					 * including idle polling cpus, for non-idle cpus, we will do nothing
 | 
				
			||||||
 | 
					 * for them.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void wake_up_all_idle_cpus(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int cpu;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						preempt_disable();
 | 
				
			||||||
 | 
						for_each_online_cpu(cpu) {
 | 
				
			||||||
 | 
							if (cpu == smp_processor_id())
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							wake_up_if_idle(cpu);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						preempt_enable();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(wake_up_all_idle_cpus);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue