smp: Provide generic idle thread allocation
[platform/kernel/linux-rpi.git] / kernel / smpboot.c
1 /*
2  * Common SMP CPU bringup/teardown functions
3  */
4 #include <linux/err.h>
5 #include <linux/smp.h>
6 #include <linux/init.h>
7 #include <linux/sched.h>
8 #include <linux/percpu.h>
9 #include <linux/workqueue.h>
10
11 #include "smpboot.h"
12
13 #ifdef CONFIG_GENERIC_SMP_IDLE_THREAD
14 struct create_idle {
15         struct work_struct      work;
16         struct task_struct      *idle;
17         struct completion       done;
18         unsigned int cpu;
19 };
20
21 static void __cpuinit do_fork_idle(struct work_struct *work)
22 {
23         struct create_idle *c = container_of(work, struct create_idle, work);
24
25         c->idle = fork_idle(c->cpu);
26         complete(&c->done);
27 }
28
29 static struct task_struct * __cpuinit idle_thread_create(unsigned int cpu)
30 {
31         struct create_idle c_idle = {
32                 .cpu    = cpu,
33                 .done   = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
34         };
35
36         INIT_WORK_ONSTACK(&c_idle.work, do_fork_idle);
37         schedule_work(&c_idle.work);
38         wait_for_completion(&c_idle.done);
39         destroy_work_on_stack(&c_idle.work);
40         return c_idle.idle;
41 }
42
43 /*
44  * For the hotplug case we keep the task structs around and reuse
45  * them.
46  */
47 static DEFINE_PER_CPU(struct task_struct *, idle_threads);
48
49 static inline struct task_struct *get_idle_for_cpu(unsigned int cpu)
50 {
51         struct task_struct *tsk = per_cpu(idle_threads, cpu);
52
53         if (!tsk)
54                 return idle_thread_create(cpu);
55         init_idle(tsk, cpu);
56         return tsk;
57 }
58
59 struct task_struct * __cpuinit idle_thread_get(unsigned int cpu)
60 {
61         return per_cpu(idle_threads, cpu);
62 }
63
64 void __init idle_thread_set_boot_cpu(void)
65 {
66         per_cpu(idle_threads, smp_processor_id()) = current;
67 }
68
69 /**
70  * idle_thread_init - Initialize the idle thread for a cpu
71  * @cpu:        The cpu for which the idle thread should be initialized
72  *
73  * Creates the thread if it does not exist.
74  */
75 static int __cpuinit idle_thread_init(unsigned int cpu)
76 {
77         struct task_struct *idle = get_idle_for_cpu(cpu);
78
79         if (IS_ERR(idle)) {
80                 printk(KERN_ERR "failed fork for CPU %u\n", cpu);
81                 return PTR_ERR(idle);
82         }
83         per_cpu(idle_threads, cpu) = idle;
84         return 0;
85 }
86 #else
87 static inline int idle_thread_init(unsigned int cpu) { return 0; }
88 #endif
89
90 /**
91  * smpboot_prepare - generic smpboot preparation
92  */
93 int __cpuinit smpboot_prepare(unsigned int cpu)
94 {
95         return idle_thread_init(cpu);
96 }