aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-04-30 10:50:17 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-04-30 10:50:17 -0400
commit8700c95adb033843fc163d112b9d21d4fda78018 (patch)
tree7bb9a37b8fe6328f63a61d88063c556346001098 /arch/ia64
parent16fa94b532b1958f508e07eca1a9256351241fbc (diff)
parentd190e8195b90bc1e65c494fe08e54e9e581bfd16 (diff)
Merge branch 'smp-hotplug-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull SMP/hotplug changes from Ingo Molnar: "This is a pretty large, multi-arch series unifying and generalizing the various disjunct pieces of idle routines that architectures have historically copied from each other and have grown in random, wildly inconsistent and sometimes buggy directions: 101 files changed, 455 insertions(+), 1328 deletions(-) this went through a number of review and test iterations before it was committed, it was tested on various architectures, was exposed to linux-next for quite some time - nevertheless it might cause problems on architectures that don't read the mailing lists and don't regularly test linux-next. This cat herding excercise was motivated by the -rt kernel, and was brought to you by Thomas "the Whip" Gleixner." * 'smp-hotplug-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (40 commits) idle: Remove GENERIC_IDLE_LOOP config switch um: Use generic idle loop ia64: Make sure interrupts enabled when we "safe_halt()" sparc: Use generic idle loop idle: Remove unused ARCH_HAS_DEFAULT_IDLE bfin: Fix typo in arch_cpu_idle() xtensa: Use generic idle loop x86: Use generic idle loop unicore: Use generic idle loop tile: Use generic idle loop tile: Enter idle with preemption disabled sh: Use generic idle loop score: Use generic idle loop s390: Use generic idle loop powerpc: Use generic idle loop parisc: Use generic idle loop openrisc: Use generic idle loop mn10300: Use generic idle loop mips: Use generic idle loop microblaze: Use generic idle loop ...
Diffstat (limited to 'arch/ia64')
-rw-r--r--arch/ia64/include/asm/irqflags.h1
-rw-r--r--arch/ia64/include/asm/thread_info.h2
-rw-r--r--arch/ia64/kernel/perfmon.c14
-rw-r--r--arch/ia64/kernel/process.c78
-rw-r--r--arch/ia64/kernel/smpboot.c2
5 files changed, 23 insertions, 74 deletions
diff --git a/arch/ia64/include/asm/irqflags.h b/arch/ia64/include/asm/irqflags.h
index 2b68d856dc78..1bf2cf2f4ab4 100644
--- a/arch/ia64/include/asm/irqflags.h
+++ b/arch/ia64/include/asm/irqflags.h
@@ -89,6 +89,7 @@ static inline bool arch_irqs_disabled(void)
89 89
90static inline void arch_safe_halt(void) 90static inline void arch_safe_halt(void)
91{ 91{
92 arch_local_irq_enable();
92 ia64_pal_halt_light(); /* PAL_HALT_LIGHT */ 93 ia64_pal_halt_light(); /* PAL_HALT_LIGHT */
93} 94}
94 95
diff --git a/arch/ia64/include/asm/thread_info.h b/arch/ia64/include/asm/thread_info.h
index 020d655ed082..cade13dd0299 100644
--- a/arch/ia64/include/asm/thread_info.h
+++ b/arch/ia64/include/asm/thread_info.h
@@ -131,8 +131,6 @@ struct thread_info {
131#define TS_POLLING 1 /* true if in idle loop and not sleeping */ 131#define TS_POLLING 1 /* true if in idle loop and not sleeping */
132#define TS_RESTORE_SIGMASK 2 /* restore signal mask in do_signal() */ 132#define TS_RESTORE_SIGMASK 2 /* restore signal mask in do_signal() */
133 133
134#define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING)
135
136#ifndef __ASSEMBLY__ 134#ifndef __ASSEMBLY__
137#define HAVE_SET_RESTORE_SIGMASK 1 135#define HAVE_SET_RESTORE_SIGMASK 1
138static inline void set_restore_sigmask(void) 136static inline void set_restore_sigmask(void)
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