aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel/process.c')
-rw-r--r--arch/sparc64/kernel/process.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index f5f97e2c669c..93557507ec9f 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -29,6 +29,7 @@
29#include <linux/compat.h> 29#include <linux/compat.h>
30#include <linux/tick.h> 30#include <linux/tick.h>
31#include <linux/init.h> 31#include <linux/init.h>
32#include <linux/cpu.h>
32 33
33#include <asm/oplib.h> 34#include <asm/oplib.h>
34#include <asm/uaccess.h> 35#include <asm/uaccess.h>
@@ -49,7 +50,7 @@
49 50
50/* #define VERBOSE_SHOWREGS */ 51/* #define VERBOSE_SHOWREGS */
51 52
52static void sparc64_yield(void) 53static void sparc64_yield(int cpu)
53{ 54{
54 if (tlb_type != hypervisor) 55 if (tlb_type != hypervisor)
55 return; 56 return;
@@ -57,7 +58,7 @@ static void sparc64_yield(void)
57 clear_thread_flag(TIF_POLLING_NRFLAG); 58 clear_thread_flag(TIF_POLLING_NRFLAG);
58 smp_mb__after_clear_bit(); 59 smp_mb__after_clear_bit();
59 60
60 while (!need_resched()) { 61 while (!need_resched() && !cpu_is_offline(cpu)) {
61 unsigned long pstate; 62 unsigned long pstate;
62 63
63 /* Disable interrupts. */ 64 /* Disable interrupts. */
@@ -68,7 +69,7 @@ static void sparc64_yield(void)
68 : "=&r" (pstate) 69 : "=&r" (pstate)
69 : "i" (PSTATE_IE)); 70 : "i" (PSTATE_IE));
70 71
71 if (!need_resched()) 72 if (!need_resched() && !cpu_is_offline(cpu))
72 sun4v_cpu_yield(); 73 sun4v_cpu_yield();
73 74
74 /* Re-enable interrupts. */ 75 /* Re-enable interrupts. */
@@ -86,15 +87,25 @@ static void sparc64_yield(void)
86/* The idle loop on sparc64. */ 87/* The idle loop on sparc64. */
87void cpu_idle(void) 88void cpu_idle(void)
88{ 89{
90 int cpu = smp_processor_id();
91
89 set_thread_flag(TIF_POLLING_NRFLAG); 92 set_thread_flag(TIF_POLLING_NRFLAG);
90 93
91 while(1) { 94 while(1) {
92 tick_nohz_stop_sched_tick(); 95 tick_nohz_stop_sched_tick();
93 while (!need_resched()) 96
94 sparc64_yield(); 97 while (!need_resched() && !cpu_is_offline(cpu))
98 sparc64_yield(cpu);
99
95 tick_nohz_restart_sched_tick(); 100 tick_nohz_restart_sched_tick();
96 101
97 preempt_enable_no_resched(); 102 preempt_enable_no_resched();
103
104#ifdef CONFIG_HOTPLUG_CPU
105 if (cpu_is_offline(cpu))
106 cpu_play_dead();
107#endif
108
98 schedule(); 109 schedule();
99 preempt_disable(); 110 preempt_disable();
100 } 111 }