aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc
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/sparc
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/sparc')
-rw-r--r--arch/sparc/include/asm/thread_info_32.h2
-rw-r--r--arch/sparc/include/asm/thread_info_64.h2
-rw-r--r--arch/sparc/kernel/hvtramp.S3
-rw-r--r--arch/sparc/kernel/process_32.c21
-rw-r--r--arch/sparc/kernel/process_64.c49
-rw-r--r--arch/sparc/kernel/smp_32.c2
-rw-r--r--arch/sparc/kernel/smp_64.c2
-rw-r--r--arch/sparc/kernel/trampoline_64.S3
8 files changed, 23 insertions, 61 deletions
diff --git a/arch/sparc/include/asm/thread_info_32.h b/arch/sparc/include/asm/thread_info_32.h
index 25849ae3e900..dd3807599bb9 100644
--- a/arch/sparc/include/asm/thread_info_32.h
+++ b/arch/sparc/include/asm/thread_info_32.h
@@ -132,8 +132,6 @@ register struct thread_info *current_thread_info_reg asm("g6");
132#define _TIF_DO_NOTIFY_RESUME_MASK (_TIF_NOTIFY_RESUME | \ 132#define _TIF_DO_NOTIFY_RESUME_MASK (_TIF_NOTIFY_RESUME | \
133 _TIF_SIGPENDING) 133 _TIF_SIGPENDING)
134 134
135#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
136
137#endif /* __KERNEL__ */ 135#endif /* __KERNEL__ */
138 136
139#endif /* _ASM_THREAD_INFO_H */ 137#endif /* _ASM_THREAD_INFO_H */
diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h
index 269bd92313df..d5e504251079 100644
--- a/arch/sparc/include/asm/thread_info_64.h
+++ b/arch/sparc/include/asm/thread_info_64.h
@@ -256,8 +256,6 @@ static inline bool test_and_clear_restore_sigmask(void)
256 return true; 256 return true;
257} 257}
258 258
259#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
260
261#define thread32_stack_is_64bit(__SP) (((__SP) & 0x1) != 0) 259#define thread32_stack_is_64bit(__SP) (((__SP) & 0x1) != 0)
262#define test_thread_64bit_stack(__SP) \ 260#define test_thread_64bit_stack(__SP) \
263 ((test_thread_flag(TIF_32BIT) && !thread32_stack_is_64bit(__SP)) ? \ 261 ((test_thread_flag(TIF_32BIT) && !thread32_stack_is_64bit(__SP)) ? \
diff --git a/arch/sparc/kernel/hvtramp.S b/arch/sparc/kernel/hvtramp.S
index 9365432904d6..605c960b2fa6 100644
--- a/arch/sparc/kernel/hvtramp.S
+++ b/arch/sparc/kernel/hvtramp.S
@@ -128,8 +128,7 @@ hv_cpu_startup:
128 128
129 call smp_callin 129 call smp_callin
130 nop 130 nop
131 call cpu_idle 131
132 mov 0, %o0
133 call cpu_panic 132 call cpu_panic
134 nop 133 nop
135 134
diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c
index 62eede13831a..c85241006e32 100644
--- a/arch/sparc/kernel/process_32.c
+++ b/arch/sparc/kernel/process_32.c
@@ -64,23 +64,12 @@ extern void fpsave(unsigned long *, unsigned long *, void *, unsigned long *);
64struct task_struct *last_task_used_math = NULL; 64struct task_struct *last_task_used_math = NULL;
65struct thread_info *current_set[NR_CPUS]; 65struct thread_info *current_set[NR_CPUS];
66 66
67/* 67/* Idle loop support. */
68 * the idle loop on a Sparc... ;) 68void arch_cpu_idle(void)
69 */
70void cpu_idle(void)
71{ 69{
72 set_thread_flag(TIF_POLLING_NRFLAG); 70 if (sparc_idle)
73 71 (*sparc_idle)();
74 /* endless idle loop with no priority at all */ 72 local_irq_enable();
75 for (;;) {
76 while (!need_resched()) {
77 if (sparc_idle)
78 (*sparc_idle)();
79 else
80 cpu_relax();
81 }
82 schedule_preempt_disabled();
83 }
84} 73}
85 74
86/* XXX cli/sti -> local_irq_xxx here, check this works once SMP is fixed. */ 75/* XXX cli/sti -> local_irq_xxx here, check this works once SMP is fixed. */
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c
index cdb80b2adbe0..9fbf0d14a361 100644
--- a/arch/sparc/kernel/process_64.c
+++ b/arch/sparc/kernel/process_64.c
@@ -52,20 +52,17 @@
52 52
53#include "kstack.h" 53#include "kstack.h"
54 54
55static void sparc64_yield(int cpu) 55/* Idle loop support on sparc64. */
56void arch_cpu_idle(void)
56{ 57{
57 if (tlb_type != hypervisor) { 58 if (tlb_type != hypervisor) {
58 touch_nmi_watchdog(); 59 touch_nmi_watchdog();
59 return; 60 } else {
60 }
61
62 clear_thread_flag(TIF_POLLING_NRFLAG);
63 smp_mb__after_clear_bit();
64
65 while (!need_resched() && !cpu_is_offline(cpu)) {
66 unsigned long pstate; 61 unsigned long pstate;
67 62
68 /* Disable interrupts. */ 63 /* The sun4v sleeping code requires that we have PSTATE.IE cleared over
64 * the cpu sleep hypervisor call.
65 */
69 __asm__ __volatile__( 66 __asm__ __volatile__(
70 "rdpr %%pstate, %0\n\t" 67 "rdpr %%pstate, %0\n\t"
71 "andn %0, %1, %0\n\t" 68 "andn %0, %1, %0\n\t"
@@ -73,7 +70,7 @@ static void sparc64_yield(int cpu)
73 : "=&r" (pstate) 70 : "=&r" (pstate)
74 : "i" (PSTATE_IE)); 71 : "i" (PSTATE_IE));
75 72
76 if (!need_resched() && !cpu_is_offline(cpu)) 73 if (!need_resched() && !cpu_is_offline(smp_processor_id()))
77 sun4v_cpu_yield(); 74 sun4v_cpu_yield();
78 75
79 /* Re-enable interrupts. */ 76 /* Re-enable interrupts. */
@@ -84,36 +81,16 @@ static void sparc64_yield(int cpu)
84 : "=&r" (pstate) 81 : "=&r" (pstate)
85 : "i" (PSTATE_IE)); 82 : "i" (PSTATE_IE));
86 } 83 }
87 84 local_irq_enable();
88 set_thread_flag(TIF_POLLING_NRFLAG);
89} 85}
90 86
91/* The idle loop on sparc64. */
92void cpu_idle(void)
93{
94 int cpu = smp_processor_id();
95
96 set_thread_flag(TIF_POLLING_NRFLAG);
97
98 while(1) {
99 tick_nohz_idle_enter();
100 rcu_idle_enter();
101
102 while (!need_resched() && !cpu_is_offline(cpu))
103 sparc64_yield(cpu);
104
105 rcu_idle_exit();
106 tick_nohz_idle_exit();
107
108#ifdef CONFIG_HOTPLUG_CPU 87#ifdef CONFIG_HOTPLUG_CPU
109 if (cpu_is_offline(cpu)) { 88void arch_cpu_idle_dead()
110 sched_preempt_enable_no_resched(); 89{
111 cpu_play_dead(); 90 sched_preempt_enable_no_resched();
112 } 91 cpu_play_dead();
113#endif
114 schedule_preempt_disabled();
115 }
116} 92}
93#endif
117 94
118#ifdef CONFIG_COMPAT 95#ifdef CONFIG_COMPAT
119static void show_regwindow32(struct pt_regs *regs) 96static void show_regwindow32(struct pt_regs *regs)
diff --git a/arch/sparc/kernel/smp_32.c b/arch/sparc/kernel/smp_32.c
index 9e7e6d718367..e3f2b81c23f1 100644
--- a/arch/sparc/kernel/smp_32.c
+++ b/arch/sparc/kernel/smp_32.c
@@ -369,7 +369,7 @@ void __cpuinit sparc_start_secondary(void *arg)
369 local_irq_enable(); 369 local_irq_enable();
370 370
371 wmb(); 371 wmb();
372 cpu_idle(); 372 cpu_startup_entry(CPUHP_ONLINE);
373 373
374 /* We should never reach here! */ 374 /* We should never reach here! */
375 BUG(); 375 BUG();
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c
index ca64d2a86ec0..77539eda928c 100644
--- a/arch/sparc/kernel/smp_64.c
+++ b/arch/sparc/kernel/smp_64.c
@@ -127,6 +127,8 @@ void __cpuinit smp_callin(void)
127 127
128 /* idle thread is expected to have preempt disabled */ 128 /* idle thread is expected to have preempt disabled */
129 preempt_disable(); 129 preempt_disable();
130
131 cpu_startup_entry(CPUHP_ONLINE);
130} 132}
131 133
132void cpu_panic(void) 134void cpu_panic(void)
diff --git a/arch/sparc/kernel/trampoline_64.S b/arch/sparc/kernel/trampoline_64.S
index da1b781b5e65..2e973a26fbda 100644
--- a/arch/sparc/kernel/trampoline_64.S
+++ b/arch/sparc/kernel/trampoline_64.S
@@ -407,8 +407,7 @@ after_lock_tlb:
407 407
408 call smp_callin 408 call smp_callin
409 nop 409 nop
410 call cpu_idle 410
411 mov 0, %o0
412 call cpu_panic 411 call cpu_panic
413 nop 412 nop
4141: b,a,pt %xcc, 1b 4131: b,a,pt %xcc, 1b