summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2013-03-21 17:49:47 -0400
committerThomas Gleixner <tglx@linutronix.de>2013-04-08 11:39:25 -0400
commit91d591c387af34db00c39da2d1d25e69a91cf591 (patch)
tree529435553ebebb83b4ed688f1e56954b72ece420 /arch
parent4e0fcc567239ef4b3f80bba778c30b0a4b624eff (diff)
ia64: Use generic idle loop
Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Rusty Russell <rusty@rustcorp.com.au> Cc: Paul McKenney <paulmck@linux.vnet.ibm.com> Cc: Peter Zijlstra <peterz@infradead.org> Reviewed-by: Cc: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com> Cc: Magnus Damm <magnus.damm@gmail.com> Cc: Tony Luck <tony.luck@intel.com> Link: http://lkml.kernel.org/r/20130321215234.406851909@linutronix.de Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch')
-rw-r--r--arch/ia64/Kconfig1
-rw-r--r--arch/ia64/kernel/perfmon.c14
-rw-r--r--arch/ia64/kernel/process.c78
-rw-r--r--arch/ia64/kernel/smpboot.c2
4 files changed, 23 insertions, 72 deletions
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 9a02f71c6b1f..e0b39c3cb789 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -35,6 +35,7 @@ config IA64
35 select ARCH_HAVE_NMI_SAFE_CMPXCHG 35 select ARCH_HAVE_NMI_SAFE_CMPXCHG
36 select GENERIC_IOMAP 36 select GENERIC_IOMAP
37 select GENERIC_SMP_IDLE_THREAD 37 select GENERIC_SMP_IDLE_THREAD
38 select GENERIC_IDLE_LOOP
38 select ARCH_INIT_TASK 39 select ARCH_INIT_TASK
39 select ARCH_TASK_STRUCT_ALLOCATOR 40 select ARCH_TASK_STRUCT_ALLOCATOR
40 select ARCH_THREAD_INFO_ALLOCATOR 41 select ARCH_THREAD_INFO_ALLOCATOR
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index 2eda28414abb..9ea25fce06d5 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -42,6 +42,7 @@
42#include <linux/completion.h> 42#include <linux/completion.h>
43#include <linux/tracehook.h> 43#include <linux/tracehook.h>
44#include <linux/slab.h> 44#include <linux/slab.h>
45#include <linux/cpu.h>
45 46
46#include <asm/errno.h> 47#include <asm/errno.h>
47#include <asm/intrinsics.h> 48#include <asm/intrinsics.h>
@@ -1322,8 +1323,6 @@ out:
1322} 1323}
1323EXPORT_SYMBOL(pfm_unregister_buffer_fmt); 1324EXPORT_SYMBOL(pfm_unregister_buffer_fmt);
1324 1325
1325extern void update_pal_halt_status(int);
1326
1327static int 1326static int
1328pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu) 1327pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu)
1329{ 1328{
@@ -1371,9 +1370,9 @@ pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu)
1371 cpu)); 1370 cpu));
1372 1371
1373 /* 1372 /*
1374 * disable default_idle() to go to PAL_HALT 1373 * Force idle() into poll mode
1375 */ 1374 */
1376 update_pal_halt_status(0); 1375 cpu_idle_poll_ctrl(true);
1377 1376
1378 UNLOCK_PFS(flags); 1377 UNLOCK_PFS(flags);
1379 1378
@@ -1430,11 +1429,8 @@ pfm_unreserve_session(pfm_context_t *ctx, int is_syswide, unsigned int cpu)
1430 is_syswide, 1429 is_syswide,
1431 cpu)); 1430 cpu));
1432 1431
1433 /* 1432 /* Undo forced polling. Last session reenables pal_halt */
1434 * if possible, enable default_idle() to go into PAL_HALT 1433 cpu_idle_poll_ctrl(false);
1435 */
1436 if (pfm_sessions.pfs_task_sessions == 0 && pfm_sessions.pfs_sys_sessions == 0)
1437 update_pal_halt_status(1);
1438 1434
1439 UNLOCK_PFS(flags); 1435 UNLOCK_PFS(flags);
1440 1436
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index 6f7dc8b7b35c..a26fc640e4ce 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -209,41 +209,13 @@ do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall)
209 local_irq_disable(); /* force interrupt disable */ 209 local_irq_disable(); /* force interrupt disable */
210} 210}
211 211
212static int pal_halt = 1;
213static int can_do_pal_halt = 1;
214
215static int __init nohalt_setup(char * str) 212static int __init nohalt_setup(char * str)
216{ 213{
217 pal_halt = can_do_pal_halt = 0; 214 cpu_idle_poll_ctrl(true);
218 return 1; 215 return 1;
219} 216}
220__setup("nohalt", nohalt_setup); 217__setup("nohalt", nohalt_setup);
221 218
222void
223update_pal_halt_status(int status)
224{
225 can_do_pal_halt = pal_halt && status;
226}
227
228/*
229 * We use this if we don't have any better idle routine..
230 */
231void
232default_idle (void)
233{
234 local_irq_enable();
235 while (!need_resched()) {
236 if (can_do_pal_halt) {
237 local_irq_disable();
238 if (!need_resched()) {
239 safe_halt();
240 }
241 local_irq_enable();
242 } else
243 cpu_relax();
244 }
245}
246
247#ifdef CONFIG_HOTPLUG_CPU 219#ifdef CONFIG_HOTPLUG_CPU
248/* We don't actually take CPU down, just spin without interrupts. */ 220/* We don't actually take CPU down, just spin without interrupts. */
249static inline void play_dead(void) 221static inline void play_dead(void)
@@ -270,47 +242,29 @@ static inline void play_dead(void)
270} 242}
271#endif /* CONFIG_HOTPLUG_CPU */ 243#endif /* CONFIG_HOTPLUG_CPU */
272 244
273void __attribute__((noreturn)) 245void arch_cpu_idle_dead(void)
274cpu_idle (void) 246{
247 play_dead();
248}
249
250void arch_cpu_idle(void)
275{ 251{
276 void (*mark_idle)(int) = ia64_mark_idle; 252 void (*mark_idle)(int) = ia64_mark_idle;
277 int cpu = smp_processor_id();
278
279 /* endless idle loop with no priority at all */
280 while (1) {
281 rcu_idle_enter();
282 if (can_do_pal_halt) {
283 current_thread_info()->status &= ~TS_POLLING;
284 /*
285 * TS_POLLING-cleared state must be visible before we
286 * test NEED_RESCHED:
287 */
288 smp_mb();
289 } else {
290 current_thread_info()->status |= TS_POLLING;
291 }
292 253
293 if (!need_resched()) {
294#ifdef CONFIG_SMP 254#ifdef CONFIG_SMP
295 min_xtp(); 255 min_xtp();
296#endif 256#endif
297 rmb(); 257 rmb();
298 if (mark_idle) 258 if (mark_idle)
299 (*mark_idle)(1); 259 (*mark_idle)(1);
260
261 safe_halt();
300 262
301 default_idle(); 263 if (mark_idle)
302 if (mark_idle) 264 (*mark_idle)(0);
303 (*mark_idle)(0);
304#ifdef CONFIG_SMP 265#ifdef CONFIG_SMP
305 normal_xtp(); 266 normal_xtp();
306#endif 267#endif
307 }
308 rcu_idle_exit();
309 schedule_preempt_disabled();
310 check_pgt_cache();
311 if (cpu_is_offline(cpu))
312 play_dead();
313 }
314} 268}
315 269
316void 270void
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
index 500f1e4d9f9d..8d87168d218d 100644
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -455,7 +455,7 @@ start_secondary (void *unused)
455 preempt_disable(); 455 preempt_disable();
456 smp_callin(); 456 smp_callin();
457 457
458 cpu_idle(); 458 cpu_startup_entry(CPUHP_ONLINE);
459 return 0; 459 return 0;
460} 460}
461 461