diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-07-18 13:53:16 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-18 13:53:16 -0400 |
commit | 9b610fda0df5d0f0b0c64242e37441ad1b384aac (patch) | |
tree | 0ea14b15f2e6546f37fe18d8ac3dc83077ec0e55 /arch/x86/kernel/process_32.c | |
parent | b8f8c3cf0a4ac0632ec3f0e15e9dc0c29de917af (diff) | |
parent | 5b664cb235e97afbf34db9c4d77f08ebd725335e (diff) |
Merge branch 'linus' into timers/nohz
Diffstat (limited to 'arch/x86/kernel/process_32.c')
-rw-r--r-- | arch/x86/kernel/process_32.c | 74 |
1 files changed, 19 insertions, 55 deletions
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 1f5fa1cf16dd..53bc653ed5ca 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c | |||
@@ -58,11 +58,6 @@ | |||
58 | 58 | ||
59 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); | 59 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); |
60 | 60 | ||
61 | static int hlt_counter; | ||
62 | |||
63 | unsigned long boot_option_idle_override = 0; | ||
64 | EXPORT_SYMBOL(boot_option_idle_override); | ||
65 | |||
66 | DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task; | 61 | DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task; |
67 | EXPORT_PER_CPU_SYMBOL(current_task); | 62 | EXPORT_PER_CPU_SYMBOL(current_task); |
68 | 63 | ||
@@ -77,57 +72,24 @@ unsigned long thread_saved_pc(struct task_struct *tsk) | |||
77 | return ((unsigned long *)tsk->thread.sp)[3]; | 72 | return ((unsigned long *)tsk->thread.sp)[3]; |
78 | } | 73 | } |
79 | 74 | ||
80 | /* | 75 | #ifdef CONFIG_HOTPLUG_CPU |
81 | * Powermanagement idle function, if any.. | 76 | #include <asm/nmi.h> |
82 | */ | ||
83 | void (*pm_idle)(void); | ||
84 | EXPORT_SYMBOL(pm_idle); | ||
85 | 77 | ||
86 | void disable_hlt(void) | 78 | static void cpu_exit_clear(void) |
87 | { | 79 | { |
88 | hlt_counter++; | 80 | int cpu = raw_smp_processor_id(); |
89 | } | ||
90 | 81 | ||
91 | EXPORT_SYMBOL(disable_hlt); | 82 | idle_task_exit(); |
92 | 83 | ||
93 | void enable_hlt(void) | 84 | cpu_uninit(); |
94 | { | 85 | irq_ctx_exit(cpu); |
95 | hlt_counter--; | ||
96 | } | ||
97 | 86 | ||
98 | EXPORT_SYMBOL(enable_hlt); | 87 | cpu_clear(cpu, cpu_callout_map); |
88 | cpu_clear(cpu, cpu_callin_map); | ||
99 | 89 | ||
100 | /* | 90 | numa_remove_cpu(cpu); |
101 | * We use this if we don't have any better | ||
102 | * idle routine.. | ||
103 | */ | ||
104 | void default_idle(void) | ||
105 | { | ||
106 | if (!hlt_counter && boot_cpu_data.hlt_works_ok) { | ||
107 | current_thread_info()->status &= ~TS_POLLING; | ||
108 | /* | ||
109 | * TS_POLLING-cleared state must be visible before we | ||
110 | * test NEED_RESCHED: | ||
111 | */ | ||
112 | smp_mb(); | ||
113 | |||
114 | if (!need_resched()) | ||
115 | safe_halt(); /* enables interrupts racelessly */ | ||
116 | else | ||
117 | local_irq_enable(); | ||
118 | current_thread_info()->status |= TS_POLLING; | ||
119 | } else { | ||
120 | local_irq_enable(); | ||
121 | /* loop is done by the caller */ | ||
122 | cpu_relax(); | ||
123 | } | ||
124 | } | 91 | } |
125 | #ifdef CONFIG_APM_MODULE | ||
126 | EXPORT_SYMBOL(default_idle); | ||
127 | #endif | ||
128 | 92 | ||
129 | #ifdef CONFIG_HOTPLUG_CPU | ||
130 | #include <asm/nmi.h> | ||
131 | /* We don't actually take CPU down, just spin without interrupts. */ | 93 | /* We don't actually take CPU down, just spin without interrupts. */ |
132 | static inline void play_dead(void) | 94 | static inline void play_dead(void) |
133 | { | 95 | { |
@@ -168,24 +130,22 @@ void cpu_idle(void) | |||
168 | while (1) { | 130 | while (1) { |
169 | tick_nohz_stop_sched_tick(1); | 131 | tick_nohz_stop_sched_tick(1); |
170 | while (!need_resched()) { | 132 | while (!need_resched()) { |
171 | void (*idle)(void); | ||
172 | 133 | ||
173 | check_pgt_cache(); | 134 | check_pgt_cache(); |
174 | rmb(); | 135 | rmb(); |
175 | idle = pm_idle; | ||
176 | 136 | ||
177 | if (rcu_pending(cpu)) | 137 | if (rcu_pending(cpu)) |
178 | rcu_check_callbacks(cpu, 0); | 138 | rcu_check_callbacks(cpu, 0); |
179 | 139 | ||
180 | if (!idle) | ||
181 | idle = default_idle; | ||
182 | |||
183 | if (cpu_is_offline(cpu)) | 140 | if (cpu_is_offline(cpu)) |
184 | play_dead(); | 141 | play_dead(); |
185 | 142 | ||
186 | local_irq_disable(); | 143 | local_irq_disable(); |
187 | __get_cpu_var(irq_stat).idle_timestamp = jiffies; | 144 | __get_cpu_var(irq_stat).idle_timestamp = jiffies; |
188 | idle(); | 145 | /* Don't trace irqs off for idle */ |
146 | stop_critical_timings(); | ||
147 | pm_idle(); | ||
148 | start_critical_timings(); | ||
189 | } | 149 | } |
190 | tick_nohz_restart_sched_tick(); | 150 | tick_nohz_restart_sched_tick(); |
191 | preempt_enable_no_resched(); | 151 | preempt_enable_no_resched(); |
@@ -333,6 +293,7 @@ void flush_thread(void) | |||
333 | /* | 293 | /* |
334 | * Forget coprocessor state.. | 294 | * Forget coprocessor state.. |
335 | */ | 295 | */ |
296 | tsk->fpu_counter = 0; | ||
336 | clear_fpu(tsk); | 297 | clear_fpu(tsk); |
337 | clear_used_math(); | 298 | clear_used_math(); |
338 | } | 299 | } |
@@ -649,8 +610,11 @@ struct task_struct * __switch_to(struct task_struct *prev_p, struct task_struct | |||
649 | /* If the task has used fpu the last 5 timeslices, just do a full | 610 | /* If the task has used fpu the last 5 timeslices, just do a full |
650 | * restore of the math state immediately to avoid the trap; the | 611 | * restore of the math state immediately to avoid the trap; the |
651 | * chances of needing FPU soon are obviously high now | 612 | * chances of needing FPU soon are obviously high now |
613 | * | ||
614 | * tsk_used_math() checks prevent calling math_state_restore(), | ||
615 | * which can sleep in the case of !tsk_used_math() | ||
652 | */ | 616 | */ |
653 | if (next_p->fpu_counter > 5) | 617 | if (tsk_used_math(next_p) && next_p->fpu_counter > 5) |
654 | math_state_restore(); | 618 | math_state_restore(); |
655 | 619 | ||
656 | /* | 620 | /* |