aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mn10300/kernel/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mn10300/kernel/process.c')
-rw-r--r--arch/mn10300/kernel/process.c61
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)
57void (*pm_power_off)(void); 57void (*pm_power_off)(void);
58EXPORT_SYMBOL(pm_power_off); 58EXPORT_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 */
79static 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 */
78void cpu_idle(void) 108void 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 */
252asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp, 284asmlinkage 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
260asmlinkage long sys_fork(void) 292asmlinkage 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
265asmlinkage long sys_vfork(void) 298asmlinkage 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
271asmlinkage long sys_execve(const char __user *name, 304asmlinkage 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}