Commit 87fa05aeb3a5e8e21b1a5510eef6983650eff092
Committed by
Thomas Gleixner
1 parent
781b0e870c
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
sparc: Use generic idle loop
Add generic cpu_idle support sparc32: - replace call to cpu_idle() with cpu_startup_entry() - add arch_cpu_idle() sparc64: - smp_callin() now include cpu_startup_entry() call so we can skip calling cpu_idle from assembler - add arch_cpu_idle() and arch_cpu_idle_dead() Signed-off-by: Sam Ravnborg <sam@ravnborg.org> Reviewed-by: "Srivatsa S. Bhat" <srivatsa.bhat@linux.vnet.ibm.com> Cc: torvalds@linux-foundation.org Cc: rusty@rustcorp.com.au Cc: paulmck@linux.vnet.ibm.com Cc: peterz@infradead.org Cc: magnus.damm@gmail.com Acked-by: David Miller <davem@davemloft.net> Link: http://lkml.kernel.org/r/20130411193850.GA2330@merkur.ravnborg.org Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Showing 7 changed files with 24 additions and 57 deletions Side-by-side Diff
arch/sparc/Kconfig
arch/sparc/kernel/hvtramp.S
arch/sparc/kernel/process_32.c
... | ... | @@ -64,23 +64,12 @@ |
64 | 64 | struct task_struct *last_task_used_math = NULL; |
65 | 65 | struct thread_info *current_set[NR_CPUS]; |
66 | 66 | |
67 | -/* | |
68 | - * the idle loop on a Sparc... ;) | |
69 | - */ | |
70 | -void cpu_idle(void) | |
67 | +/* Idle loop support. */ | |
68 | +void arch_cpu_idle(void) | |
71 | 69 | { |
72 | - set_thread_flag(TIF_POLLING_NRFLAG); | |
73 | - | |
74 | - /* endless idle loop with no priority at all */ | |
75 | - for (;;) { | |
76 | - while (!need_resched()) { | |
77 | - if (sparc_idle) | |
78 | - (*sparc_idle)(); | |
79 | - else | |
80 | - cpu_relax(); | |
81 | - } | |
82 | - schedule_preempt_disabled(); | |
83 | - } | |
70 | + if (sparc_idle) | |
71 | + (*sparc_idle)(); | |
72 | + local_irq_enable(); | |
84 | 73 | } |
85 | 74 | |
86 | 75 | /* XXX cli/sti -> local_irq_xxx here, check this works once SMP is fixed. */ |
arch/sparc/kernel/process_64.c
... | ... | @@ -52,20 +52,17 @@ |
52 | 52 | |
53 | 53 | #include "kstack.h" |
54 | 54 | |
55 | -static void sparc64_yield(int cpu) | |
55 | +/* Idle loop support on sparc64. */ | |
56 | +void arch_cpu_idle(void) | |
56 | 57 | { |
57 | 58 | if (tlb_type != hypervisor) { |
58 | 59 | touch_nmi_watchdog(); |
59 | - return; | |
60 | - } | |
61 | - | |
62 | - clear_thread_flag(TIF_POLLING_NRFLAG); | |
63 | - smp_mb__after_clear_bit(); | |
64 | - | |
65 | - while (!need_resched() && !cpu_is_offline(cpu)) { | |
60 | + } else { | |
66 | 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 | 66 | __asm__ __volatile__( |
70 | 67 | "rdpr %%pstate, %0\n\t" |
71 | 68 | "andn %0, %1, %0\n\t" |
... | ... | @@ -73,7 +70,7 @@ |
73 | 70 | : "=&r" (pstate) |
74 | 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 | 74 | sun4v_cpu_yield(); |
78 | 75 | |
79 | 76 | /* Re-enable interrupts. */ |
80 | 77 | |
81 | 78 | |
82 | 79 | |
... | ... | @@ -84,36 +81,16 @@ |
84 | 81 | : "=&r" (pstate) |
85 | 82 | : "i" (PSTATE_IE)); |
86 | 83 | } |
87 | - | |
88 | - set_thread_flag(TIF_POLLING_NRFLAG); | |
84 | + local_irq_enable(); | |
89 | 85 | } |
90 | 86 | |
91 | -/* The idle loop on sparc64. */ | |
92 | -void 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 | 87 | #ifdef CONFIG_HOTPLUG_CPU |
109 | - if (cpu_is_offline(cpu)) { | |
110 | - sched_preempt_enable_no_resched(); | |
111 | - cpu_play_dead(); | |
112 | - } | |
113 | -#endif | |
114 | - schedule_preempt_disabled(); | |
115 | - } | |
88 | +void arch_cpu_idle_dead() | |
89 | +{ | |
90 | + sched_preempt_enable_no_resched(); | |
91 | + cpu_play_dead(); | |
116 | 92 | } |
93 | +#endif | |
117 | 94 | |
118 | 95 | #ifdef CONFIG_COMPAT |
119 | 96 | static void show_regwindow32(struct pt_regs *regs) |
arch/sparc/kernel/smp_32.c
arch/sparc/kernel/smp_64.c