aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/cpu.c')
-rw-r--r--kernel/cpu.c34
1 files changed, 18 insertions, 16 deletions
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 28cb6c71a47a..369d2892687d 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -120,12 +120,13 @@ static int take_cpu_down(void *unused)
120} 120}
121 121
122/* Requires cpu_add_remove_lock to be held */ 122/* Requires cpu_add_remove_lock to be held */
123static int _cpu_down(unsigned int cpu) 123static int _cpu_down(unsigned int cpu, int tasks_frozen)
124{ 124{
125 int err, nr_calls = 0; 125 int err, nr_calls = 0;
126 struct task_struct *p; 126 struct task_struct *p;
127 cpumask_t old_allowed, tmp; 127 cpumask_t old_allowed, tmp;
128 void *hcpu = (void *)(long)cpu; 128 void *hcpu = (void *)(long)cpu;
129 unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0;
129 130
130 if (num_online_cpus() == 1) 131 if (num_online_cpus() == 1)
131 return -EBUSY; 132 return -EBUSY;
@@ -134,11 +135,11 @@ static int _cpu_down(unsigned int cpu)
134 return -EINVAL; 135 return -EINVAL;
135 136
136 raw_notifier_call_chain(&cpu_chain, CPU_LOCK_ACQUIRE, hcpu); 137 raw_notifier_call_chain(&cpu_chain, CPU_LOCK_ACQUIRE, hcpu);
137 err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE, 138 err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE | mod,
138 hcpu, -1, &nr_calls); 139 hcpu, -1, &nr_calls);
139 if (err == NOTIFY_BAD) { 140 if (err == NOTIFY_BAD) {
140 __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED, hcpu, 141 __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED | mod,
141 nr_calls, NULL); 142 hcpu, nr_calls, NULL);
142 printk("%s: attempt to take down CPU %u failed\n", 143 printk("%s: attempt to take down CPU %u failed\n",
143 __FUNCTION__, cpu); 144 __FUNCTION__, cpu);
144 err = -EINVAL; 145 err = -EINVAL;
@@ -157,7 +158,7 @@ static int _cpu_down(unsigned int cpu)
157 158
158 if (IS_ERR(p) || cpu_online(cpu)) { 159 if (IS_ERR(p) || cpu_online(cpu)) {
159 /* CPU didn't die: tell everyone. Can't complain. */ 160 /* CPU didn't die: tell everyone. Can't complain. */
160 if (raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED, 161 if (raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED | mod,
161 hcpu) == NOTIFY_BAD) 162 hcpu) == NOTIFY_BAD)
162 BUG(); 163 BUG();
163 164
@@ -176,7 +177,8 @@ static int _cpu_down(unsigned int cpu)
176 __cpu_die(cpu); 177 __cpu_die(cpu);
177 178
178 /* CPU is completely dead: tell everyone. Too late to complain. */ 179 /* CPU is completely dead: tell everyone. Too late to complain. */
179 if (raw_notifier_call_chain(&cpu_chain, CPU_DEAD, hcpu) == NOTIFY_BAD) 180 if (raw_notifier_call_chain(&cpu_chain, CPU_DEAD | mod,
181 hcpu) == NOTIFY_BAD)
180 BUG(); 182 BUG();
181 183
182 check_for_tasks(cpu); 184 check_for_tasks(cpu);
@@ -186,8 +188,7 @@ out_thread:
186out_allowed: 188out_allowed:
187 set_cpus_allowed(current, old_allowed); 189 set_cpus_allowed(current, old_allowed);
188out_release: 190out_release:
189 raw_notifier_call_chain(&cpu_chain, CPU_LOCK_RELEASE, 191 raw_notifier_call_chain(&cpu_chain, CPU_LOCK_RELEASE, hcpu);
190 (void *)(long)cpu);
191 return err; 192 return err;
192} 193}
193 194
@@ -199,7 +200,7 @@ int cpu_down(unsigned int cpu)
199 if (cpu_hotplug_disabled) 200 if (cpu_hotplug_disabled)
200 err = -EBUSY; 201 err = -EBUSY;
201 else 202 else
202 err = _cpu_down(cpu); 203 err = _cpu_down(cpu, 0);
203 204
204 mutex_unlock(&cpu_add_remove_lock); 205 mutex_unlock(&cpu_add_remove_lock);
205 return err; 206 return err;
@@ -207,16 +208,17 @@ int cpu_down(unsigned int cpu)
207#endif /*CONFIG_HOTPLUG_CPU*/ 208#endif /*CONFIG_HOTPLUG_CPU*/
208 209
209/* Requires cpu_add_remove_lock to be held */ 210/* Requires cpu_add_remove_lock to be held */
210static int __cpuinit _cpu_up(unsigned int cpu) 211static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen)
211{ 212{
212 int ret, nr_calls = 0; 213 int ret, nr_calls = 0;
213 void *hcpu = (void *)(long)cpu; 214 void *hcpu = (void *)(long)cpu;
215 unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0;
214 216
215 if (cpu_online(cpu) || !cpu_present(cpu)) 217 if (cpu_online(cpu) || !cpu_present(cpu))
216 return -EINVAL; 218 return -EINVAL;
217 219
218 raw_notifier_call_chain(&cpu_chain, CPU_LOCK_ACQUIRE, hcpu); 220 raw_notifier_call_chain(&cpu_chain, CPU_LOCK_ACQUIRE, hcpu);
219 ret = __raw_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu, 221 ret = __raw_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE | mod, hcpu,
220 -1, &nr_calls); 222 -1, &nr_calls);
221 if (ret == NOTIFY_BAD) { 223 if (ret == NOTIFY_BAD) {
222 printk("%s: attempt to bring up CPU %u failed\n", 224 printk("%s: attempt to bring up CPU %u failed\n",
@@ -234,12 +236,12 @@ static int __cpuinit _cpu_up(unsigned int cpu)
234 BUG_ON(!cpu_online(cpu)); 236 BUG_ON(!cpu_online(cpu));
235 237
236 /* Now call notifier in preparation. */ 238 /* Now call notifier in preparation. */
237 raw_notifier_call_chain(&cpu_chain, CPU_ONLINE, hcpu); 239 raw_notifier_call_chain(&cpu_chain, CPU_ONLINE | mod, hcpu);
238 240
239out_notify: 241out_notify:
240 if (ret != 0) 242 if (ret != 0)
241 __raw_notifier_call_chain(&cpu_chain, 243 __raw_notifier_call_chain(&cpu_chain,
242 CPU_UP_CANCELED, hcpu, nr_calls, NULL); 244 CPU_UP_CANCELED | mod, hcpu, nr_calls, NULL);
243 raw_notifier_call_chain(&cpu_chain, CPU_LOCK_RELEASE, hcpu); 245 raw_notifier_call_chain(&cpu_chain, CPU_LOCK_RELEASE, hcpu);
244 246
245 return ret; 247 return ret;
@@ -253,7 +255,7 @@ int __cpuinit cpu_up(unsigned int cpu)
253 if (cpu_hotplug_disabled) 255 if (cpu_hotplug_disabled)
254 err = -EBUSY; 256 err = -EBUSY;
255 else 257 else
256 err = _cpu_up(cpu); 258 err = _cpu_up(cpu, 0);
257 259
258 mutex_unlock(&cpu_add_remove_lock); 260 mutex_unlock(&cpu_add_remove_lock);
259 return err; 261 return err;
@@ -283,7 +285,7 @@ int disable_nonboot_cpus(void)
283 for_each_online_cpu(cpu) { 285 for_each_online_cpu(cpu) {
284 if (cpu == first_cpu) 286 if (cpu == first_cpu)
285 continue; 287 continue;
286 error = _cpu_down(cpu); 288 error = _cpu_down(cpu, 1);
287 if (!error) { 289 if (!error) {
288 cpu_set(cpu, frozen_cpus); 290 cpu_set(cpu, frozen_cpus);
289 printk("CPU%d is down\n", cpu); 291 printk("CPU%d is down\n", cpu);
@@ -318,7 +320,7 @@ void enable_nonboot_cpus(void)
318 suspend_cpu_hotplug = 1; 320 suspend_cpu_hotplug = 1;
319 printk("Enabling non-boot CPUs ...\n"); 321 printk("Enabling non-boot CPUs ...\n");
320 for_each_cpu_mask(cpu, frozen_cpus) { 322 for_each_cpu_mask(cpu, frozen_cpus) {
321 error = _cpu_up(cpu); 323 error = _cpu_up(cpu, 1);
322 if (!error) { 324 if (!error) {
323 printk("CPU%d is up\n", cpu); 325 printk("CPU%d is up\n", cpu);
324 continue; 326 continue;