diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2007-07-16 06:49:40 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-07-16 07:05:32 -0400 |
commit | e0204409df29fe1b7d18f81dfc3ae6f9d90e7a63 (patch) | |
tree | 66f670c0f182d02185f2f3ea6bb7bb97c165ff3b /arch/sparc64/kernel/process.c | |
parent | f3c681c028846bd5d39f563909409832a295ca69 (diff) |
[SPARC64]: dr-cpu unconfigure support.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/process.c')
-rw-r--r-- | arch/sparc64/kernel/process.c | 21 |
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 | ||
52 | static void sparc64_yield(void) | 53 | static 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. */ |
87 | void cpu_idle(void) | 88 | void 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 | } |