X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=arch%2Fia64%2Fkernel%2Fprocess.c;h=91293388dd2947c67d941f7b487b100bb7060fdc;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=56ffa1a5dd3b667407714c9b4a00dee29c6b8980;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index 56ffa1a5d..91293388d 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -39,6 +40,8 @@ #include #include +#include "entry.h" + #ifdef CONFIG_PERFMON # include #endif @@ -46,7 +49,10 @@ #include "sigframe.h" void (*ia64_mark_idle)(int); +static cpumask_t cpu_idle_map; +unsigned long boot_option_idle_override = 0; +EXPORT_SYMBOL(boot_option_idle_override); void ia64_do_show_stack (struct unw_frame_info *info, void *arg) @@ -185,6 +191,8 @@ default_idle (void) while (!need_resched()) if (pal_halt && !pmu_active) safe_halt(); + else + cpu_relax(); } #ifdef CONFIG_HOTPLUG_CPU @@ -221,10 +229,28 @@ static inline void play_dead(void) } #endif /* CONFIG_HOTPLUG_CPU */ + +void cpu_idle_wait(void) +{ + int cpu; + cpumask_t map; + + for_each_online_cpu(cpu) + cpu_set(cpu, cpu_idle_map); + + wmb(); + do { + ssleep(1); + cpus_and(map, cpu_idle_map, cpu_online_map); + } while (!cpus_empty(map)); +} +EXPORT_SYMBOL_GPL(cpu_idle_wait); + void __attribute__((noreturn)) -cpu_idle (void *unused) +cpu_idle (void) { void (*mark_idle)(int) = ia64_mark_idle; + int cpu = smp_processor_id(); /* endless idle loop with no priority at all */ while (1) { @@ -237,17 +263,14 @@ cpu_idle (void *unused) if (mark_idle) (*mark_idle)(1); - /* - * Mark this as an RCU critical section so that - * synchronize_kernel() in the unload path waits - * for our completion. - */ - rcu_read_lock(); + + if (cpu_isset(cpu, cpu_idle_map)) + cpu_clear(cpu, cpu_idle_map); + rmb(); idle = pm_idle; if (!idle) idle = default_idle; (*idle)(); - rcu_read_unlock(); } if (mark_idle) @@ -609,7 +632,7 @@ dump_fpu (struct pt_regs *pt, elf_fpregset_t dst) return 1; /* f0-f31 are always valid so we always return 1 */ } -asmlinkage long +long sys_execve (char __user *filename, char __user * __user *argv, char __user * __user *envp, struct pt_regs *regs) { @@ -646,7 +669,7 @@ kernel_thread (int (*fn)(void *), void *arg, unsigned long flags) regs.pt.cr_ifs = 1UL << 63; /* mark as valid, empty frame */ regs.sw.ar_fpsr = regs.pt.ar_fpsr = ia64_getreg(_IA64_REG_AR_FPSR); regs.sw.ar_bspstore = (unsigned long) current + IA64_RBS_OFFSET; - + regs.sw.pr = (1 << PRED_KERNEL_STACK); return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s.pt, 0, NULL, NULL); } EXPORT_SYMBOL(kernel_thread);