1 #include <linux/stop_machine.h>
2 #include <linux/kthread.h>
3 #include <linux/sched.h>
6 #include <linux/syscalls.h>
7 #include <asm/atomic.h>
8 #include <asm/semaphore.h>
10 /* Since we effect priority and affinity (both of which are visible
11 * to, and settable by outside processes) we do indirection via a
14 /* Thread to stop each CPU in user context. */
15 enum stopmachine_state {
18 STOPMACHINE_DISABLE_IRQ,
22 static enum stopmachine_state stopmachine_state;
23 static unsigned int stopmachine_num_threads;
24 static atomic_t stopmachine_thread_ack;
25 static DECLARE_MUTEX(stopmachine_mutex);
27 static int stopmachine(void *cpu)
29 int irqs_disabled = 0;
32 set_cpus_allowed(current, cpumask_of_cpu((int)(long)cpu));
34 /* Ack: we are alive */
35 mb(); /* Theoretically the ack = 0 might not be on this CPU yet. */
36 atomic_inc(&stopmachine_thread_ack);
38 /* Simple state machine */
39 while (stopmachine_state != STOPMACHINE_EXIT) {
40 if (stopmachine_state == STOPMACHINE_DISABLE_IRQ
44 /* Ack: irqs disabled. */
45 mb(); /* Must read state first. */
46 atomic_inc(&stopmachine_thread_ack);
47 } else if (stopmachine_state == STOPMACHINE_PREPARE
49 /* Everyone is in place, hold CPU. */
52 mb(); /* Must read state first. */
53 atomic_inc(&stopmachine_thread_ack);
55 /* Yield in first stage: migration threads need to
56 * help our sisters onto their CPUs. */
57 if (!prepared && !irqs_disabled)
63 /* Ack: we are exiting. */
64 mb(); /* Must read state first. */
65 atomic_inc(&stopmachine_thread_ack);
75 /* Change the thread state */
76 static void stopmachine_set_state(enum stopmachine_state state)
78 atomic_set(&stopmachine_thread_ack, 0);
80 stopmachine_state = state;
81 while (atomic_read(&stopmachine_thread_ack) != stopmachine_num_threads)
85 static int stop_machine(void)
88 struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
90 /* One high-prio thread per cpu. We'll do this one. */
91 sys_sched_setscheduler(current->pid, SCHED_FIFO, ¶m);
93 atomic_set(&stopmachine_thread_ack, 0);
94 stopmachine_num_threads = 0;
95 stopmachine_state = STOPMACHINE_WAIT;
97 for_each_online_cpu(i) {
98 if (i == smp_processor_id())
100 ret = kernel_thread(stopmachine, (void *)(long)i,CLONE_KERNEL);
103 stopmachine_num_threads++;
106 /* Wait for them all to come to life. */
107 while (atomic_read(&stopmachine_thread_ack) != stopmachine_num_threads)
110 /* If some failed, kill them all. */
112 stopmachine_set_state(STOPMACHINE_EXIT);
113 up(&stopmachine_mutex);
117 /* Don't schedule us away at this point, please. */
120 /* Now they are all started, make them hold the CPUs, ready. */
121 stopmachine_set_state(STOPMACHINE_PREPARE);
123 /* Make them disable irqs. */
124 stopmachine_set_state(STOPMACHINE_DISABLE_IRQ);
129 static void restart_machine(void)
131 stopmachine_set_state(STOPMACHINE_EXIT);
135 struct stop_machine_data
139 struct completion done;
142 static int do_stop(void *_smdata)
144 struct stop_machine_data *smdata = _smdata;
147 ret = stop_machine();
149 ret = smdata->fn(smdata->data);
153 /* We're done: you can kthread_stop us now */
154 complete(&smdata->done);
156 /* Wait for kthread_stop */
157 set_current_state(TASK_INTERRUPTIBLE);
158 while (!kthread_should_stop()) {
160 set_current_state(TASK_INTERRUPTIBLE);
162 __set_current_state(TASK_RUNNING);
166 struct task_struct *__stop_machine_run(int (*fn)(void *), void *data,
169 struct stop_machine_data smdata;
170 struct task_struct *p;
174 init_completion(&smdata.done);
176 down(&stopmachine_mutex);
178 /* If they don't care which CPU fn runs on, bind to any online one. */
180 cpu = smp_processor_id();
182 p = kthread_create(do_stop, &smdata, "kstopmachine");
184 kthread_bind(p, cpu);
186 wait_for_completion(&smdata.done);
188 up(&stopmachine_mutex);
192 int stop_machine_run(int (*fn)(void *), void *data, unsigned int cpu)
194 struct task_struct *p;
197 /* No CPUs can come up or down during this. */
199 p = __stop_machine_run(fn, data, cpu);
201 ret = kthread_stop(p);
204 unlock_cpu_hotplug();