History

[PATCH] Convert cpu hotplug notifiers to use raw_notifier instead of blocking_notifier

The use of blocking notifier by _cpu_up and _cpu_down in cpu.c has two problem. 1/ An interaction with the workqueue notifier causes lockdep to spit a warning. 2/ A notifier could conceivable be added or removed while _cpu_up or _cpu_down are in process. As each notifier is called twice (prepare then commit/abort) this could be unhealthy. To fix to we simply take cpu_add_remove_lock while adding or removing notifiers to/from the list. This makes the 'blocking' usage unnecessary as all accesses to cpu_chain are now protected by cpu_add_remove_lock. So change "blocking" to "raw" in all relevant places. This fixes 1.

Neil Brown committed 20 years ago

Commit bd5349c1 parent bea493a1 file · +15 −9Browse files

Showing the changes to kernel/cpu.c (1 of 1 file). Show all

Unified · Split

kernel/cpu.c+15−9
@@ -19,7 +19,7 @@ · 18 unmodified lines
1919 static DEFINE_MUTEX(cpu_add_remove_lock);
2020 static DEFINE_MUTEX(cpu_bitmask_lock);
2121
22−static __cpuinitdata BLOCKING_NOTIFIER_HEAD(cpu_chain);
22+static __cpuinitdata RAW_NOTIFIER_HEAD(cpu_chain);
2323
2424 /* If set, cpu_up and cpu_down will return -EBUSY and do nothing.
2525 * Should always be manipulated under cpu_add_remove_lock
@@ -68,7 +68,11 @@ EXPORT_SYMBOL_GPL(unlock_cpu_hotplug); · 42 unmodified lines
6868 /* Need to know about CPUs going up/down? */
6969 int __cpuinit register_cpu_notifier(struct notifier_block *nb)
7070 {
71− return blocking_notifier_chain_register(&cpu_chain, nb);
71+ int ret;
72+ mutex_lock(&cpu_add_remove_lock);
73+ ret = raw_notifier_chain_register(&cpu_chain, nb);
74+ mutex_unlock(&cpu_add_remove_lock);
75+ return ret;
7276 }
7377
7478 #ifdef CONFIG_HOTPLUG_CPU
@@ -77,7 +81,9 @@ EXPORT_SYMBOL(register_cpu_notifier); · 2 unmodified lines
7781
7882 void unregister_cpu_notifier(struct notifier_block *nb)
7983 {
80− blocking_notifier_chain_unregister(&cpu_chain, nb);
84+ mutex_lock(&cpu_add_remove_lock);
85+ raw_notifier_chain_unregister(&cpu_chain, nb);
86+ mutex_unlock(&cpu_add_remove_lock);
8187 }
8288 EXPORT_SYMBOL(unregister_cpu_notifier);
8389
@@ -126,7 +132,7 @@ static int _cpu_down(unsigned int cpu) · 42 unmodified lines
126132 if (!cpu_online(cpu))
127133 return -EINVAL;
128134
129− err = blocking_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE,
135+ err = raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE,
130136 (void *)(long)cpu);
131137 if (err == NOTIFY_BAD) {
132138 printk("%s: attempt to take down CPU %u failed\n",
@@ -146,7 +152,7 @@ static int _cpu_down(unsigned int cpu) · 13 unmodified lines
146152
147153 if (IS_ERR(p)) {
148154 /* CPU didn't die: tell everyone. Can't complain. */
149− if (blocking_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED,
155+ if (raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED,
150156 (void *)(long)cpu) == NOTIFY_BAD)
151157 BUG();
152158
@@ -169,7 +175,7 @@ static int _cpu_down(unsigned int cpu) · 16 unmodified lines
169175 put_cpu();
170176
171177 /* CPU is completely dead: tell everyone. Too late to complain. */
172− if (blocking_notifier_call_chain(&cpu_chain, CPU_DEAD,
178+ if (raw_notifier_call_chain(&cpu_chain, CPU_DEAD,
173179 (void *)(long)cpu) == NOTIFY_BAD)
174180 BUG();
175181
@@ -206,7 +212,7 @@ static int __devinit _cpu_up(unsigned int cpu) · 30 unmodified lines
206212 if (cpu_online(cpu) || !cpu_present(cpu))
207213 return -EINVAL;
208214
209− ret = blocking_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu);
215+ ret = raw_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu);
210216 if (ret == NOTIFY_BAD) {
211217 printk("%s: attempt to bring up CPU %u failed\n",
212218 __FUNCTION__, cpu);
@@ -223,11 +229,11 @@ static int __devinit _cpu_up(unsigned int cpu) · 10 unmodified lines
223229 BUG_ON(!cpu_online(cpu));
224230
225231 /* Now call notifier in preparation. */
226− blocking_notifier_call_chain(&cpu_chain, CPU_ONLINE, hcpu);
232+ raw_notifier_call_chain(&cpu_chain, CPU_ONLINE, hcpu);
227233
228234 out_notify:
229235 if (ret != 0)
230− blocking_notifier_call_chain(&cpu_chain,
236+ raw_notifier_call_chain(&cpu_chain,
231237 CPU_UP_CANCELED, hcpu);
232238
233239 return ret;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t