diff options
Diffstat (limited to 'arch/mn10300/kernel/process.c')
| -rw-r--r-- | arch/mn10300/kernel/process.c | 61 |
1 files changed, 47 insertions, 14 deletions
diff --git a/arch/mn10300/kernel/process.c b/arch/mn10300/kernel/process.c index f48373e2bc1c..0d0f8049a17b 100644 --- a/arch/mn10300/kernel/process.c +++ b/arch/mn10300/kernel/process.c | |||
| @@ -57,6 +57,7 @@ unsigned long thread_saved_pc(struct task_struct *tsk) | |||
| 57 | void (*pm_power_off)(void); | 57 | void (*pm_power_off)(void); |
| 58 | EXPORT_SYMBOL(pm_power_off); | 58 | EXPORT_SYMBOL(pm_power_off); |
| 59 | 59 | ||
| 60 | #if !defined(CONFIG_SMP) || defined(CONFIG_HOTPLUG_CPU) | ||
| 60 | /* | 61 | /* |
| 61 | * we use this if we don't have any better idle routine | 62 | * we use this if we don't have any better idle routine |
| 62 | */ | 63 | */ |
| @@ -69,6 +70,35 @@ static void default_idle(void) | |||
| 69 | local_irq_enable(); | 70 | local_irq_enable(); |
| 70 | } | 71 | } |
| 71 | 72 | ||
| 73 | #else /* !CONFIG_SMP || CONFIG_HOTPLUG_CPU */ | ||
| 74 | /* | ||
| 75 | * On SMP it's slightly faster (but much more power-consuming!) | ||
| 76 | * to poll the ->work.need_resched flag instead of waiting for the | ||
| 77 | * cross-CPU IPI to arrive. Use this option with caution. | ||
| 78 | */ | ||
| 79 | static inline void poll_idle(void) | ||
| 80 | { | ||
| 81 | int oldval; | ||
| 82 | |||
| 83 | local_irq_enable(); | ||
| 84 | |||
| 85 | /* | ||
| 86 | * Deal with another CPU just having chosen a thread to | ||
| 87 | * run here: | ||
| 88 | */ | ||
| 89 | oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED); | ||
| 90 | |||
| 91 | if (!oldval) { | ||
| 92 | set_thread_flag(TIF_POLLING_NRFLAG); | ||
| 93 | while (!need_resched()) | ||
| 94 | cpu_relax(); | ||
| 95 | clear_thread_flag(TIF_POLLING_NRFLAG); | ||
| 96 | } else { | ||
| 97 | set_need_resched(); | ||
| 98 | } | ||
| 99 | } | ||
| 100 | #endif /* !CONFIG_SMP || CONFIG_HOTPLUG_CPU */ | ||
| 101 | |||
| 72 | /* | 102 | /* |
| 73 | * the idle thread | 103 | * the idle thread |
| 74 | * - there's no useful work to be done, so just try to conserve power and have | 104 | * - there's no useful work to be done, so just try to conserve power and have |
| @@ -77,8 +107,6 @@ static void default_idle(void) | |||
| 77 | */ | 107 | */ |
| 78 | void cpu_idle(void) | 108 | void cpu_idle(void) |
| 79 | { | 109 | { |
| 80 | int cpu = smp_processor_id(); | ||
| 81 | |||
| 82 | /* endless idle loop with no priority at all */ | 110 | /* endless idle loop with no priority at all */ |
| 83 | for (;;) { | 111 | for (;;) { |
| 84 | while (!need_resched()) { | 112 | while (!need_resched()) { |
| @@ -86,10 +114,13 @@ void cpu_idle(void) | |||
| 86 | 114 | ||
| 87 | smp_rmb(); | 115 | smp_rmb(); |
| 88 | idle = pm_idle; | 116 | idle = pm_idle; |
| 89 | if (!idle) | 117 | if (!idle) { |
| 118 | #if defined(CONFIG_SMP) && !defined(CONFIG_HOTPLUG_CPU) | ||
| 119 | idle = poll_idle; | ||
| 120 | #else /* CONFIG_SMP && !CONFIG_HOTPLUG_CPU */ | ||
| 90 | idle = default_idle; | 121 | idle = default_idle; |
| 91 | 122 | #endif /* CONFIG_SMP && !CONFIG_HOTPLUG_CPU */ | |
| 92 | irq_stat[cpu].idle_timestamp = jiffies; | 123 | } |
| 93 | idle(); | 124 | idle(); |
| 94 | } | 125 | } |
| 95 | 126 | ||
| @@ -197,6 +228,7 @@ int copy_thread(unsigned long clone_flags, | |||
| 197 | unsigned long c_usp, unsigned long ustk_size, | 228 | unsigned long c_usp, unsigned long ustk_size, |
| 198 | struct task_struct *p, struct pt_regs *kregs) | 229 | struct task_struct *p, struct pt_regs *kregs) |
| 199 | { | 230 | { |
| 231 | struct thread_info *ti = task_thread_info(p); | ||
| 200 | struct pt_regs *c_uregs, *c_kregs, *uregs; | 232 | struct pt_regs *c_uregs, *c_kregs, *uregs; |
| 201 | unsigned long c_ksp; | 233 | unsigned long c_ksp; |
| 202 | 234 | ||
| @@ -217,7 +249,7 @@ int copy_thread(unsigned long clone_flags, | |||
| 217 | 249 | ||
| 218 | /* the new TLS pointer is passed in as arg #5 to sys_clone() */ | 250 | /* the new TLS pointer is passed in as arg #5 to sys_clone() */ |
| 219 | if (clone_flags & CLONE_SETTLS) | 251 | if (clone_flags & CLONE_SETTLS) |
| 220 | c_uregs->e2 = __frame->d3; | 252 | c_uregs->e2 = current_frame()->d3; |
| 221 | 253 | ||
| 222 | /* set up the return kernel frame if called from kernel_thread() */ | 254 | /* set up the return kernel frame if called from kernel_thread() */ |
| 223 | c_kregs = c_uregs; | 255 | c_kregs = c_uregs; |
| @@ -235,7 +267,7 @@ int copy_thread(unsigned long clone_flags, | |||
| 235 | } | 267 | } |
| 236 | 268 | ||
| 237 | /* set up things up so the scheduler can start the new task */ | 269 | /* set up things up so the scheduler can start the new task */ |
| 238 | p->thread.__frame = c_kregs; | 270 | ti->frame = c_kregs; |
| 239 | p->thread.a3 = (unsigned long) c_kregs; | 271 | p->thread.a3 = (unsigned long) c_kregs; |
| 240 | p->thread.sp = c_ksp; | 272 | p->thread.sp = c_ksp; |
| 241 | p->thread.pc = (unsigned long) ret_from_fork; | 273 | p->thread.pc = (unsigned long) ret_from_fork; |
| @@ -247,25 +279,26 @@ int copy_thread(unsigned long clone_flags, | |||
| 247 | 279 | ||
| 248 | /* | 280 | /* |
| 249 | * clone a process | 281 | * clone a process |
| 250 | * - tlsptr is retrieved by copy_thread() from __frame->d3 | 282 | * - tlsptr is retrieved by copy_thread() from current_frame()->d3 |
| 251 | */ | 283 | */ |
| 252 | asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp, | 284 | asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp, |
| 253 | int __user *parent_tidptr, int __user *child_tidptr, | 285 | int __user *parent_tidptr, int __user *child_tidptr, |
| 254 | int __user *tlsptr) | 286 | int __user *tlsptr) |
| 255 | { | 287 | { |
| 256 | return do_fork(clone_flags, newsp ?: __frame->sp, __frame, 0, | 288 | return do_fork(clone_flags, newsp ?: current_frame()->sp, |
| 257 | parent_tidptr, child_tidptr); | 289 | current_frame(), 0, parent_tidptr, child_tidptr); |
| 258 | } | 290 | } |
| 259 | 291 | ||
| 260 | asmlinkage long sys_fork(void) | 292 | asmlinkage long sys_fork(void) |
| 261 | { | 293 | { |
| 262 | return do_fork(SIGCHLD, __frame->sp, __frame, 0, NULL, NULL); | 294 | return do_fork(SIGCHLD, current_frame()->sp, |
| 295 | current_frame(), 0, NULL, NULL); | ||
| 263 | } | 296 | } |
| 264 | 297 | ||
| 265 | asmlinkage long sys_vfork(void) | 298 | asmlinkage long sys_vfork(void) |
| 266 | { | 299 | { |
| 267 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, __frame->sp, __frame, | 300 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, current_frame()->sp, |
| 268 | 0, NULL, NULL); | 301 | current_frame(), 0, NULL, NULL); |
| 269 | } | 302 | } |
| 270 | 303 | ||
| 271 | asmlinkage long sys_execve(const char __user *name, | 304 | asmlinkage long sys_execve(const char __user *name, |
| @@ -279,7 +312,7 @@ asmlinkage long sys_execve(const char __user *name, | |||
| 279 | error = PTR_ERR(filename); | 312 | error = PTR_ERR(filename); |
| 280 | if (IS_ERR(filename)) | 313 | if (IS_ERR(filename)) |
| 281 | return error; | 314 | return error; |
| 282 | error = do_execve(filename, argv, envp, __frame); | 315 | error = do_execve(filename, argv, envp, current_frame()); |
| 283 | putname(filename); | 316 | putname(filename); |
| 284 | return error; | 317 | return error; |
| 285 | } | 318 | } |
