diff options
-rw-r--r-- | include/linux/notifier.h | 2 | ||||
-rw-r--r-- | kernel/cpu.c | 19 |
2 files changed, 16 insertions, 5 deletions
diff --git a/include/linux/notifier.h b/include/linux/notifier.h index e34221bf8946..1903e5490c04 100644 --- a/include/linux/notifier.h +++ b/include/linux/notifier.h | |||
@@ -194,6 +194,8 @@ extern int __srcu_notifier_call_chain(struct srcu_notifier_head *nh, | |||
194 | #define CPU_DOWN_PREPARE 0x0005 /* CPU (unsigned)v going down */ | 194 | #define CPU_DOWN_PREPARE 0x0005 /* CPU (unsigned)v going down */ |
195 | #define CPU_DOWN_FAILED 0x0006 /* CPU (unsigned)v NOT going down */ | 195 | #define CPU_DOWN_FAILED 0x0006 /* CPU (unsigned)v NOT going down */ |
196 | #define CPU_DEAD 0x0007 /* CPU (unsigned)v dead */ | 196 | #define CPU_DEAD 0x0007 /* CPU (unsigned)v dead */ |
197 | #define CPU_LOCK_ACQUIRE 0x0008 /* Acquire all hotcpu locks */ | ||
198 | #define CPU_LOCK_RELEASE 0x0009 /* Release all hotcpu locks */ | ||
197 | 199 | ||
198 | #endif /* __KERNEL__ */ | 200 | #endif /* __KERNEL__ */ |
199 | #endif /* _LINUX_NOTIFIER_H */ | 201 | #endif /* _LINUX_NOTIFIER_H */ |
diff --git a/kernel/cpu.c b/kernel/cpu.c index 36e70845cfc3..48810498b355 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
@@ -132,12 +132,15 @@ static int _cpu_down(unsigned int cpu) | |||
132 | if (!cpu_online(cpu)) | 132 | if (!cpu_online(cpu)) |
133 | return -EINVAL; | 133 | return -EINVAL; |
134 | 134 | ||
135 | raw_notifier_call_chain(&cpu_chain, CPU_LOCK_ACQUIRE, | ||
136 | (void *)(long)cpu); | ||
135 | err = raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE, | 137 | err = raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE, |
136 | (void *)(long)cpu); | 138 | (void *)(long)cpu); |
137 | if (err == NOTIFY_BAD) { | 139 | if (err == NOTIFY_BAD) { |
138 | printk("%s: attempt to take down CPU %u failed\n", | 140 | printk("%s: attempt to take down CPU %u failed\n", |
139 | __FUNCTION__, cpu); | 141 | __FUNCTION__, cpu); |
140 | return -EINVAL; | 142 | err = -EINVAL; |
143 | goto out_release; | ||
141 | } | 144 | } |
142 | 145 | ||
143 | /* Ensure that we are not runnable on dying cpu */ | 146 | /* Ensure that we are not runnable on dying cpu */ |
@@ -185,6 +188,9 @@ out_thread: | |||
185 | err = kthread_stop(p); | 188 | err = kthread_stop(p); |
186 | out_allowed: | 189 | out_allowed: |
187 | set_cpus_allowed(current, old_allowed); | 190 | set_cpus_allowed(current, old_allowed); |
191 | out_release: | ||
192 | raw_notifier_call_chain(&cpu_chain, CPU_LOCK_RELEASE, | ||
193 | (void *)(long)cpu); | ||
188 | return err; | 194 | return err; |
189 | } | 195 | } |
190 | 196 | ||
@@ -206,13 +212,15 @@ int cpu_down(unsigned int cpu) | |||
206 | /* Requires cpu_add_remove_lock to be held */ | 212 | /* Requires cpu_add_remove_lock to be held */ |
207 | static int __cpuinit _cpu_up(unsigned int cpu) | 213 | static int __cpuinit _cpu_up(unsigned int cpu) |
208 | { | 214 | { |
209 | int ret; | 215 | int ret, nr_calls = 0; |
210 | void *hcpu = (void *)(long)cpu; | 216 | void *hcpu = (void *)(long)cpu; |
211 | 217 | ||
212 | if (cpu_online(cpu) || !cpu_present(cpu)) | 218 | if (cpu_online(cpu) || !cpu_present(cpu)) |
213 | return -EINVAL; | 219 | return -EINVAL; |
214 | 220 | ||
215 | ret = raw_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu); | 221 | raw_notifier_call_chain(&cpu_chain, CPU_LOCK_ACQUIRE, hcpu); |
222 | ret = __raw_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu, | ||
223 | -1, &nr_calls); | ||
216 | if (ret == NOTIFY_BAD) { | 224 | if (ret == NOTIFY_BAD) { |
217 | printk("%s: attempt to bring up CPU %u failed\n", | 225 | printk("%s: attempt to bring up CPU %u failed\n", |
218 | __FUNCTION__, cpu); | 226 | __FUNCTION__, cpu); |
@@ -233,8 +241,9 @@ static int __cpuinit _cpu_up(unsigned int cpu) | |||
233 | 241 | ||
234 | out_notify: | 242 | out_notify: |
235 | if (ret != 0) | 243 | if (ret != 0) |
236 | raw_notifier_call_chain(&cpu_chain, | 244 | __raw_notifier_call_chain(&cpu_chain, |
237 | CPU_UP_CANCELED, hcpu); | 245 | CPU_UP_CANCELED, hcpu, nr_calls, NULL); |
246 | raw_notifier_call_chain(&cpu_chain, CPU_LOCK_RELEASE, hcpu); | ||
238 | 247 | ||
239 | return ret; | 248 | return ret; |
240 | } | 249 | } |