diff options
| author | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-11-22 13:06:44 -0500 |
|---|---|---|
| committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-11-22 13:06:44 -0500 |
| commit | 0bd2af46839ad6262d25714a6ec0365db9d6b98f (patch) | |
| tree | dcced72d230d69fd0c5816ac6dd03ab84799a93e /arch/i386/kernel/process.c | |
| parent | e138a5d2356729b8752e88520cc1525fae9794ac (diff) | |
| parent | f26b90440cd74c78fe10c9bd5160809704a9627c (diff) | |
Merge ../scsi-rc-fixes-2.6
Diffstat (limited to 'arch/i386/kernel/process.c')
| -rw-r--r-- | arch/i386/kernel/process.c | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index b0a07801d9df..dd53c58f64f1 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c | |||
| @@ -205,7 +205,7 @@ void cpu_idle(void) | |||
| 205 | void cpu_idle_wait(void) | 205 | void cpu_idle_wait(void) |
| 206 | { | 206 | { |
| 207 | unsigned int cpu, this_cpu = get_cpu(); | 207 | unsigned int cpu, this_cpu = get_cpu(); |
| 208 | cpumask_t map; | 208 | cpumask_t map, tmp = current->cpus_allowed; |
| 209 | 209 | ||
| 210 | set_cpus_allowed(current, cpumask_of_cpu(this_cpu)); | 210 | set_cpus_allowed(current, cpumask_of_cpu(this_cpu)); |
| 211 | put_cpu(); | 211 | put_cpu(); |
| @@ -227,6 +227,8 @@ void cpu_idle_wait(void) | |||
| 227 | } | 227 | } |
| 228 | cpus_and(map, map, cpu_online_map); | 228 | cpus_and(map, map, cpu_online_map); |
| 229 | } while (!cpus_empty(map)); | 229 | } while (!cpus_empty(map)); |
| 230 | |||
| 231 | set_cpus_allowed(current, tmp); | ||
| 230 | } | 232 | } |
| 231 | EXPORT_SYMBOL_GPL(cpu_idle_wait); | 233 | EXPORT_SYMBOL_GPL(cpu_idle_wait); |
| 232 | 234 | ||
| @@ -236,20 +238,28 @@ EXPORT_SYMBOL_GPL(cpu_idle_wait); | |||
| 236 | * We execute MONITOR against need_resched and enter optimized wait state | 238 | * We execute MONITOR against need_resched and enter optimized wait state |
| 237 | * through MWAIT. Whenever someone changes need_resched, we would be woken | 239 | * through MWAIT. Whenever someone changes need_resched, we would be woken |
| 238 | * up from MWAIT (without an IPI). | 240 | * up from MWAIT (without an IPI). |
| 241 | * | ||
| 242 | * New with Core Duo processors, MWAIT can take some hints based on CPU | ||
| 243 | * capability. | ||
| 239 | */ | 244 | */ |
| 240 | static void mwait_idle(void) | 245 | void mwait_idle_with_hints(unsigned long eax, unsigned long ecx) |
| 241 | { | 246 | { |
| 242 | local_irq_enable(); | 247 | if (!need_resched()) { |
| 243 | |||
| 244 | while (!need_resched()) { | ||
| 245 | __monitor((void *)¤t_thread_info()->flags, 0, 0); | 248 | __monitor((void *)¤t_thread_info()->flags, 0, 0); |
| 246 | smp_mb(); | 249 | smp_mb(); |
| 247 | if (need_resched()) | 250 | if (!need_resched()) |
| 248 | break; | 251 | __mwait(eax, ecx); |
| 249 | __mwait(0, 0); | ||
| 250 | } | 252 | } |
| 251 | } | 253 | } |
| 252 | 254 | ||
| 255 | /* Default MONITOR/MWAIT with no hints, used for default C1 state */ | ||
| 256 | static void mwait_idle(void) | ||
| 257 | { | ||
| 258 | local_irq_enable(); | ||
| 259 | while (!need_resched()) | ||
| 260 | mwait_idle_with_hints(0, 0); | ||
| 261 | } | ||
| 262 | |||
| 253 | void __devinit select_idle_routine(const struct cpuinfo_x86 *c) | 263 | void __devinit select_idle_routine(const struct cpuinfo_x86 *c) |
| 254 | { | 264 | { |
| 255 | if (cpu_has(c, X86_FEATURE_MWAIT)) { | 265 | if (cpu_has(c, X86_FEATURE_MWAIT)) { |
| @@ -328,7 +338,6 @@ extern void kernel_thread_helper(void); | |||
| 328 | int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) | 338 | int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) |
| 329 | { | 339 | { |
| 330 | struct pt_regs regs; | 340 | struct pt_regs regs; |
| 331 | int err; | ||
| 332 | 341 | ||
| 333 | memset(®s, 0, sizeof(regs)); | 342 | memset(®s, 0, sizeof(regs)); |
| 334 | 343 | ||
| @@ -343,10 +352,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) | |||
| 343 | regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2; | 352 | regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2; |
| 344 | 353 | ||
| 345 | /* Ok, create the new process.. */ | 354 | /* Ok, create the new process.. */ |
| 346 | err = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); | 355 | return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); |
| 347 | if (err == 0) /* terminate kernel stack */ | ||
| 348 | task_pt_regs(current)->eip = 0; | ||
| 349 | return err; | ||
| 350 | } | 356 | } |
| 351 | EXPORT_SYMBOL(kernel_thread); | 357 | EXPORT_SYMBOL(kernel_thread); |
| 352 | 358 | ||
