diff options
63 files changed, 677 insertions, 472 deletions
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index 9402624453c2..dd8769670596 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c | |||
@@ -43,7 +43,7 @@ | |||
43 | #include <asm/setup.h> | 43 | #include <asm/setup.h> |
44 | #include <asm/io.h> | 44 | #include <asm/io.h> |
45 | 45 | ||
46 | extern struct notifier_block *panic_notifier_list; | 46 | extern struct atomic_notifier_head panic_notifier_list; |
47 | static int alpha_panic_event(struct notifier_block *, unsigned long, void *); | 47 | static int alpha_panic_event(struct notifier_block *, unsigned long, void *); |
48 | static struct notifier_block alpha_panic_block = { | 48 | static struct notifier_block alpha_panic_block = { |
49 | alpha_panic_event, | 49 | alpha_panic_event, |
@@ -500,7 +500,8 @@ setup_arch(char **cmdline_p) | |||
500 | } | 500 | } |
501 | 501 | ||
502 | /* Register a call for panic conditions. */ | 502 | /* Register a call for panic conditions. */ |
503 | notifier_chain_register(&panic_notifier_list, &alpha_panic_block); | 503 | atomic_notifier_chain_register(&panic_notifier_list, |
504 | &alpha_panic_block); | ||
504 | 505 | ||
505 | #ifdef CONFIG_ALPHA_GENERIC | 506 | #ifdef CONFIG_ALPHA_GENERIC |
506 | /* Assume that we've booted from SRM if we haven't booted from MILO. | 507 | /* Assume that we've booted from SRM if we haven't booted from MILO. |
diff --git a/arch/arm/mach-omap1/board-netstar.c b/arch/arm/mach-omap1/board-netstar.c index 60d5f8a3339c..7520e602d7a2 100644 --- a/arch/arm/mach-omap1/board-netstar.c +++ b/arch/arm/mach-omap1/board-netstar.c | |||
@@ -141,7 +141,7 @@ static int __init netstar_late_init(void) | |||
141 | /* TODO: Setup front panel switch here */ | 141 | /* TODO: Setup front panel switch here */ |
142 | 142 | ||
143 | /* Setup panic notifier */ | 143 | /* Setup panic notifier */ |
144 | notifier_chain_register(&panic_notifier_list, &panic_block); | 144 | atomic_notifier_chain_register(&panic_notifier_list, &panic_block); |
145 | 145 | ||
146 | return 0; | 146 | return 0; |
147 | } | 147 | } |
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c index bfd5fdd1a875..52e4a9d69642 100644 --- a/arch/arm/mach-omap1/board-voiceblue.c +++ b/arch/arm/mach-omap1/board-voiceblue.c | |||
@@ -235,7 +235,7 @@ static struct notifier_block panic_block = { | |||
235 | static int __init voiceblue_setup(void) | 235 | static int __init voiceblue_setup(void) |
236 | { | 236 | { |
237 | /* Setup panic notifier */ | 237 | /* Setup panic notifier */ |
238 | notifier_chain_register(&panic_notifier_list, &panic_block); | 238 | atomic_notifier_chain_register(&panic_notifier_list, &panic_block); |
239 | 239 | ||
240 | return 0; | 240 | return 0; |
241 | } | 241 | } |
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 4624f8ca2459..6b63a5aa1e46 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c | |||
@@ -92,22 +92,21 @@ asmlinkage void spurious_interrupt_bug(void); | |||
92 | asmlinkage void machine_check(void); | 92 | asmlinkage void machine_check(void); |
93 | 93 | ||
94 | static int kstack_depth_to_print = 24; | 94 | static int kstack_depth_to_print = 24; |
95 | struct notifier_block *i386die_chain; | 95 | ATOMIC_NOTIFIER_HEAD(i386die_chain); |
96 | static DEFINE_SPINLOCK(die_notifier_lock); | ||
97 | 96 | ||
98 | int register_die_notifier(struct notifier_block *nb) | 97 | int register_die_notifier(struct notifier_block *nb) |
99 | { | 98 | { |
100 | int err = 0; | ||
101 | unsigned long flags; | ||
102 | |||
103 | vmalloc_sync_all(); | 99 | vmalloc_sync_all(); |
104 | spin_lock_irqsave(&die_notifier_lock, flags); | 100 | return atomic_notifier_chain_register(&i386die_chain, nb); |
105 | err = notifier_chain_register(&i386die_chain, nb); | ||
106 | spin_unlock_irqrestore(&die_notifier_lock, flags); | ||
107 | return err; | ||
108 | } | 101 | } |
109 | EXPORT_SYMBOL(register_die_notifier); | 102 | EXPORT_SYMBOL(register_die_notifier); |
110 | 103 | ||
104 | int unregister_die_notifier(struct notifier_block *nb) | ||
105 | { | ||
106 | return atomic_notifier_chain_unregister(&i386die_chain, nb); | ||
107 | } | ||
108 | EXPORT_SYMBOL(unregister_die_notifier); | ||
109 | |||
111 | static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) | 110 | static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) |
112 | { | 111 | { |
113 | return p > (void *)tinfo && | 112 | return p > (void *)tinfo && |
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c index dabd6c32641e..7c1ddc8ac443 100644 --- a/arch/ia64/kernel/traps.c +++ b/arch/ia64/kernel/traps.c | |||
@@ -30,19 +30,19 @@ extern spinlock_t timerlist_lock; | |||
30 | fpswa_interface_t *fpswa_interface; | 30 | fpswa_interface_t *fpswa_interface; |
31 | EXPORT_SYMBOL(fpswa_interface); | 31 | EXPORT_SYMBOL(fpswa_interface); |
32 | 32 | ||
33 | struct notifier_block *ia64die_chain; | 33 | ATOMIC_NOTIFIER_HEAD(ia64die_chain); |
34 | 34 | ||
35 | int | 35 | int |
36 | register_die_notifier(struct notifier_block *nb) | 36 | register_die_notifier(struct notifier_block *nb) |
37 | { | 37 | { |
38 | return notifier_chain_register(&ia64die_chain, nb); | 38 | return atomic_notifier_chain_register(&ia64die_chain, nb); |
39 | } | 39 | } |
40 | EXPORT_SYMBOL_GPL(register_die_notifier); | 40 | EXPORT_SYMBOL_GPL(register_die_notifier); |
41 | 41 | ||
42 | int | 42 | int |
43 | unregister_die_notifier(struct notifier_block *nb) | 43 | unregister_die_notifier(struct notifier_block *nb) |
44 | { | 44 | { |
45 | return notifier_chain_unregister(&ia64die_chain, nb); | 45 | return atomic_notifier_chain_unregister(&ia64die_chain, nb); |
46 | } | 46 | } |
47 | EXPORT_SYMBOL_GPL(unregister_die_notifier); | 47 | EXPORT_SYMBOL_GPL(unregister_die_notifier); |
48 | 48 | ||
diff --git a/arch/mips/lasat/setup.c b/arch/mips/lasat/setup.c index 83eb08b7a072..e9e9a89c6741 100644 --- a/arch/mips/lasat/setup.c +++ b/arch/mips/lasat/setup.c | |||
@@ -165,7 +165,8 @@ void __init plat_setup(void) | |||
165 | 165 | ||
166 | /* Set up panic notifier */ | 166 | /* Set up panic notifier */ |
167 | for (i = 0; i < sizeof(lasat_panic_block) / sizeof(struct notifier_block); i++) | 167 | for (i = 0; i < sizeof(lasat_panic_block) / sizeof(struct notifier_block); i++) |
168 | notifier_chain_register(&panic_notifier_list, &lasat_panic_block[i]); | 168 | atomic_notifier_chain_register(&panic_notifier_list, |
169 | &lasat_panic_block[i]); | ||
169 | 170 | ||
170 | lasat_reboot_setup(); | 171 | lasat_reboot_setup(); |
171 | 172 | ||
diff --git a/arch/mips/sgi-ip22/ip22-reset.c b/arch/mips/sgi-ip22/ip22-reset.c index 92a3b3c15ed3..a9c58e067b53 100644 --- a/arch/mips/sgi-ip22/ip22-reset.c +++ b/arch/mips/sgi-ip22/ip22-reset.c | |||
@@ -238,7 +238,7 @@ static int __init reboot_setup(void) | |||
238 | request_irq(SGI_PANEL_IRQ, panel_int, 0, "Front Panel", NULL); | 238 | request_irq(SGI_PANEL_IRQ, panel_int, 0, "Front Panel", NULL); |
239 | init_timer(&blink_timer); | 239 | init_timer(&blink_timer); |
240 | blink_timer.function = blink_timeout; | 240 | blink_timer.function = blink_timeout; |
241 | notifier_chain_register(&panic_notifier_list, &panic_block); | 241 | atomic_notifier_chain_register(&panic_notifier_list, &panic_block); |
242 | 242 | ||
243 | return 0; | 243 | return 0; |
244 | } | 244 | } |
diff --git a/arch/mips/sgi-ip32/ip32-reset.c b/arch/mips/sgi-ip32/ip32-reset.c index 0c948008b023..ab9d9cef089e 100644 --- a/arch/mips/sgi-ip32/ip32-reset.c +++ b/arch/mips/sgi-ip32/ip32-reset.c | |||
@@ -193,7 +193,7 @@ static __init int ip32_reboot_setup(void) | |||
193 | 193 | ||
194 | init_timer(&blink_timer); | 194 | init_timer(&blink_timer); |
195 | blink_timer.function = blink_timeout; | 195 | blink_timer.function = blink_timeout; |
196 | notifier_chain_register(&panic_notifier_list, &panic_block); | 196 | atomic_notifier_chain_register(&panic_notifier_list, &panic_block); |
197 | 197 | ||
198 | request_irq(MACEISA_RTC_IRQ, ip32_rtc_int, 0, "rtc", NULL); | 198 | request_irq(MACEISA_RTC_IRQ, ip32_rtc_int, 0, "rtc", NULL); |
199 | 199 | ||
diff --git a/arch/parisc/kernel/pdc_chassis.c b/arch/parisc/kernel/pdc_chassis.c index 2a01fe1bdc98..0cea6958f427 100644 --- a/arch/parisc/kernel/pdc_chassis.c +++ b/arch/parisc/kernel/pdc_chassis.c | |||
@@ -150,7 +150,8 @@ void __init parisc_pdc_chassis_init(void) | |||
150 | 150 | ||
151 | if (handle) { | 151 | if (handle) { |
152 | /* initialize panic notifier chain */ | 152 | /* initialize panic notifier chain */ |
153 | notifier_chain_register(&panic_notifier_list, &pdc_chassis_panic_block); | 153 | atomic_notifier_chain_register(&panic_notifier_list, |
154 | &pdc_chassis_panic_block); | ||
154 | 155 | ||
155 | /* initialize reboot notifier chain */ | 156 | /* initialize reboot notifier chain */ |
156 | register_reboot_notifier(&pdc_chassis_reboot_block); | 157 | register_reboot_notifier(&pdc_chassis_reboot_block); |
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 2f3fdad35594..e20c1fae3423 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
@@ -579,7 +579,8 @@ void __init setup_arch(char **cmdline_p) | |||
579 | panic_timeout = 180; | 579 | panic_timeout = 180; |
580 | 580 | ||
581 | if (ppc_md.panic) | 581 | if (ppc_md.panic) |
582 | notifier_chain_register(&panic_notifier_list, &ppc64_panic_block); | 582 | atomic_notifier_chain_register(&panic_notifier_list, |
583 | &ppc64_panic_block); | ||
583 | 584 | ||
584 | init_mm.start_code = PAGE_OFFSET; | 585 | init_mm.start_code = PAGE_OFFSET; |
585 | init_mm.end_code = (unsigned long) _etext; | 586 | init_mm.end_code = (unsigned long) _etext; |
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 98660aedeeb7..9763faab6739 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
@@ -74,19 +74,19 @@ EXPORT_SYMBOL(__debugger_dabr_match); | |||
74 | EXPORT_SYMBOL(__debugger_fault_handler); | 74 | EXPORT_SYMBOL(__debugger_fault_handler); |
75 | #endif | 75 | #endif |
76 | 76 | ||
77 | struct notifier_block *powerpc_die_chain; | 77 | ATOMIC_NOTIFIER_HEAD(powerpc_die_chain); |
78 | static DEFINE_SPINLOCK(die_notifier_lock); | ||
79 | 78 | ||
80 | int register_die_notifier(struct notifier_block *nb) | 79 | int register_die_notifier(struct notifier_block *nb) |
81 | { | 80 | { |
82 | int err = 0; | 81 | return atomic_notifier_chain_register(&powerpc_die_chain, nb); |
83 | unsigned long flags; | 82 | } |
83 | EXPORT_SYMBOL(register_die_notifier); | ||
84 | 84 | ||
85 | spin_lock_irqsave(&die_notifier_lock, flags); | 85 | int unregister_die_notifier(struct notifier_block *nb) |
86 | err = notifier_chain_register(&powerpc_die_chain, nb); | 86 | { |
87 | spin_unlock_irqrestore(&die_notifier_lock, flags); | 87 | return atomic_notifier_chain_unregister(&powerpc_die_chain, nb); |
88 | return err; | ||
89 | } | 88 | } |
89 | EXPORT_SYMBOL(unregister_die_notifier); | ||
90 | 90 | ||
91 | /* | 91 | /* |
92 | * Trap & Exception support | 92 | * Trap & Exception support |
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c index 86cfa6ecdcf3..5ad90676567a 100644 --- a/arch/powerpc/platforms/pseries/reconfig.c +++ b/arch/powerpc/platforms/pseries/reconfig.c | |||
@@ -94,16 +94,16 @@ static struct device_node *derive_parent(const char *path) | |||
94 | return parent; | 94 | return parent; |
95 | } | 95 | } |
96 | 96 | ||
97 | static struct notifier_block *pSeries_reconfig_chain; | 97 | static BLOCKING_NOTIFIER_HEAD(pSeries_reconfig_chain); |
98 | 98 | ||
99 | int pSeries_reconfig_notifier_register(struct notifier_block *nb) | 99 | int pSeries_reconfig_notifier_register(struct notifier_block *nb) |
100 | { | 100 | { |
101 | return notifier_chain_register(&pSeries_reconfig_chain, nb); | 101 | return blocking_notifier_chain_register(&pSeries_reconfig_chain, nb); |
102 | } | 102 | } |
103 | 103 | ||
104 | void pSeries_reconfig_notifier_unregister(struct notifier_block *nb) | 104 | void pSeries_reconfig_notifier_unregister(struct notifier_block *nb) |
105 | { | 105 | { |
106 | notifier_chain_unregister(&pSeries_reconfig_chain, nb); | 106 | blocking_notifier_chain_unregister(&pSeries_reconfig_chain, nb); |
107 | } | 107 | } |
108 | 108 | ||
109 | static int pSeries_reconfig_add_node(const char *path, struct property *proplist) | 109 | static int pSeries_reconfig_add_node(const char *path, struct property *proplist) |
@@ -131,7 +131,7 @@ static int pSeries_reconfig_add_node(const char *path, struct property *proplist | |||
131 | goto out_err; | 131 | goto out_err; |
132 | } | 132 | } |
133 | 133 | ||
134 | err = notifier_call_chain(&pSeries_reconfig_chain, | 134 | err = blocking_notifier_call_chain(&pSeries_reconfig_chain, |
135 | PSERIES_RECONFIG_ADD, np); | 135 | PSERIES_RECONFIG_ADD, np); |
136 | if (err == NOTIFY_BAD) { | 136 | if (err == NOTIFY_BAD) { |
137 | printk(KERN_ERR "Failed to add device node %s\n", path); | 137 | printk(KERN_ERR "Failed to add device node %s\n", path); |
@@ -171,7 +171,7 @@ static int pSeries_reconfig_remove_node(struct device_node *np) | |||
171 | 171 | ||
172 | remove_node_proc_entries(np); | 172 | remove_node_proc_entries(np); |
173 | 173 | ||
174 | notifier_call_chain(&pSeries_reconfig_chain, | 174 | blocking_notifier_call_chain(&pSeries_reconfig_chain, |
175 | PSERIES_RECONFIG_REMOVE, np); | 175 | PSERIES_RECONFIG_REMOVE, np); |
176 | of_detach_node(np); | 176 | of_detach_node(np); |
177 | 177 | ||
diff --git a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c index a0fc628ffb1e..d95c05d9824d 100644 --- a/arch/ppc/platforms/prep_setup.c +++ b/arch/ppc/platforms/prep_setup.c | |||
@@ -736,7 +736,7 @@ ibm_statusled_progress(char *s, unsigned short hex) | |||
736 | hex = 0xfff; | 736 | hex = 0xfff; |
737 | if (!notifier_installed) { | 737 | if (!notifier_installed) { |
738 | ++notifier_installed; | 738 | ++notifier_installed; |
739 | notifier_chain_register(&panic_notifier_list, | 739 | atomic_notifier_chain_register(&panic_notifier_list, |
740 | &ibm_statusled_block); | 740 | &ibm_statusled_block); |
741 | } | 741 | } |
742 | } | 742 | } |
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 99182a415fe7..4a0f5a1551ea 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c | |||
@@ -76,17 +76,17 @@ unsigned long thread_saved_pc(struct task_struct *tsk) | |||
76 | /* | 76 | /* |
77 | * Need to know about CPUs going idle? | 77 | * Need to know about CPUs going idle? |
78 | */ | 78 | */ |
79 | static struct notifier_block *idle_chain; | 79 | static ATOMIC_NOTIFIER_HEAD(idle_chain); |
80 | 80 | ||
81 | int register_idle_notifier(struct notifier_block *nb) | 81 | int register_idle_notifier(struct notifier_block *nb) |
82 | { | 82 | { |
83 | return notifier_chain_register(&idle_chain, nb); | 83 | return atomic_notifier_chain_register(&idle_chain, nb); |
84 | } | 84 | } |
85 | EXPORT_SYMBOL(register_idle_notifier); | 85 | EXPORT_SYMBOL(register_idle_notifier); |
86 | 86 | ||
87 | int unregister_idle_notifier(struct notifier_block *nb) | 87 | int unregister_idle_notifier(struct notifier_block *nb) |
88 | { | 88 | { |
89 | return notifier_chain_unregister(&idle_chain, nb); | 89 | return atomic_notifier_chain_unregister(&idle_chain, nb); |
90 | } | 90 | } |
91 | EXPORT_SYMBOL(unregister_idle_notifier); | 91 | EXPORT_SYMBOL(unregister_idle_notifier); |
92 | 92 | ||
@@ -95,7 +95,7 @@ void do_monitor_call(struct pt_regs *regs, long interruption_code) | |||
95 | /* disable monitor call class 0 */ | 95 | /* disable monitor call class 0 */ |
96 | __ctl_clear_bit(8, 15); | 96 | __ctl_clear_bit(8, 15); |
97 | 97 | ||
98 | notifier_call_chain(&idle_chain, CPU_NOT_IDLE, | 98 | atomic_notifier_call_chain(&idle_chain, CPU_NOT_IDLE, |
99 | (void *)(long) smp_processor_id()); | 99 | (void *)(long) smp_processor_id()); |
100 | } | 100 | } |
101 | 101 | ||
@@ -116,7 +116,8 @@ static void default_idle(void) | |||
116 | return; | 116 | return; |
117 | } | 117 | } |
118 | 118 | ||
119 | rc = notifier_call_chain(&idle_chain, CPU_IDLE, (void *)(long) cpu); | 119 | rc = atomic_notifier_call_chain(&idle_chain, |
120 | CPU_IDLE, (void *)(long) cpu); | ||
120 | if (rc != NOTIFY_OK && rc != NOTIFY_DONE) | 121 | if (rc != NOTIFY_OK && rc != NOTIFY_DONE) |
121 | BUG(); | 122 | BUG(); |
122 | if (rc != NOTIFY_OK) { | 123 | if (rc != NOTIFY_OK) { |
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index df612e4f75f9..ff090bb9734b 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c | |||
@@ -43,18 +43,19 @@ | |||
43 | #include <linux/kmod.h> | 43 | #include <linux/kmod.h> |
44 | #endif | 44 | #endif |
45 | 45 | ||
46 | struct notifier_block *sparc64die_chain; | 46 | ATOMIC_NOTIFIER_HEAD(sparc64die_chain); |
47 | static DEFINE_SPINLOCK(die_notifier_lock); | ||
48 | 47 | ||
49 | int register_die_notifier(struct notifier_block *nb) | 48 | int register_die_notifier(struct notifier_block *nb) |
50 | { | 49 | { |
51 | int err = 0; | 50 | return atomic_notifier_chain_register(&sparc64die_chain, nb); |
52 | unsigned long flags; | ||
53 | spin_lock_irqsave(&die_notifier_lock, flags); | ||
54 | err = notifier_chain_register(&sparc64die_chain, nb); | ||
55 | spin_unlock_irqrestore(&die_notifier_lock, flags); | ||
56 | return err; | ||
57 | } | 51 | } |
52 | EXPORT_SYMBOL(register_die_notifier); | ||
53 | |||
54 | int unregister_die_notifier(struct notifier_block *nb) | ||
55 | { | ||
56 | return atomic_notifier_chain_unregister(&sparc64die_chain, nb); | ||
57 | } | ||
58 | EXPORT_SYMBOL(unregister_die_notifier); | ||
58 | 59 | ||
59 | /* When an irrecoverable trap occurs at tl > 0, the trap entry | 60 | /* When an irrecoverable trap occurs at tl > 0, the trap entry |
60 | * code logs the trap state registers at every level in the trap | 61 | * code logs the trap state registers at every level in the trap |
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index 54388d10bcf9..1488816588ea 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c | |||
@@ -762,7 +762,8 @@ static struct notifier_block panic_exit_notifier = { | |||
762 | 762 | ||
763 | static int add_notifier(void) | 763 | static int add_notifier(void) |
764 | { | 764 | { |
765 | notifier_chain_register(&panic_notifier_list, &panic_exit_notifier); | 765 | atomic_notifier_chain_register(&panic_notifier_list, |
766 | &panic_exit_notifier); | ||
766 | return(0); | 767 | return(0); |
767 | } | 768 | } |
768 | 769 | ||
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index bb1c87211ac1..7d51dd7201c3 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c | |||
@@ -477,7 +477,8 @@ static struct notifier_block panic_exit_notifier = { | |||
477 | 477 | ||
478 | void __init setup_arch(char **cmdline_p) | 478 | void __init setup_arch(char **cmdline_p) |
479 | { | 479 | { |
480 | notifier_chain_register(&panic_notifier_list, &panic_exit_notifier); | 480 | atomic_notifier_chain_register(&panic_notifier_list, |
481 | &panic_exit_notifier); | ||
481 | paging_init(); | 482 | paging_init(); |
482 | strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE); | 483 | strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE); |
483 | *cmdline_p = command_line; | 484 | *cmdline_p = command_line; |
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c index 0370720515f1..70dd8e5c6889 100644 --- a/arch/x86_64/kernel/process.c +++ b/arch/x86_64/kernel/process.c | |||
@@ -66,24 +66,17 @@ EXPORT_SYMBOL(boot_option_idle_override); | |||
66 | void (*pm_idle)(void); | 66 | void (*pm_idle)(void); |
67 | static DEFINE_PER_CPU(unsigned int, cpu_idle_state); | 67 | static DEFINE_PER_CPU(unsigned int, cpu_idle_state); |
68 | 68 | ||
69 | static struct notifier_block *idle_notifier; | 69 | static ATOMIC_NOTIFIER_HEAD(idle_notifier); |
70 | static DEFINE_SPINLOCK(idle_notifier_lock); | ||
71 | 70 | ||
72 | void idle_notifier_register(struct notifier_block *n) | 71 | void idle_notifier_register(struct notifier_block *n) |
73 | { | 72 | { |
74 | unsigned long flags; | 73 | atomic_notifier_chain_register(&idle_notifier, n); |
75 | spin_lock_irqsave(&idle_notifier_lock, flags); | ||
76 | notifier_chain_register(&idle_notifier, n); | ||
77 | spin_unlock_irqrestore(&idle_notifier_lock, flags); | ||
78 | } | 74 | } |
79 | EXPORT_SYMBOL_GPL(idle_notifier_register); | 75 | EXPORT_SYMBOL_GPL(idle_notifier_register); |
80 | 76 | ||
81 | void idle_notifier_unregister(struct notifier_block *n) | 77 | void idle_notifier_unregister(struct notifier_block *n) |
82 | { | 78 | { |
83 | unsigned long flags; | 79 | atomic_notifier_chain_unregister(&idle_notifier, n); |
84 | spin_lock_irqsave(&idle_notifier_lock, flags); | ||
85 | notifier_chain_unregister(&idle_notifier, n); | ||
86 | spin_unlock_irqrestore(&idle_notifier_lock, flags); | ||
87 | } | 80 | } |
88 | EXPORT_SYMBOL(idle_notifier_unregister); | 81 | EXPORT_SYMBOL(idle_notifier_unregister); |
89 | 82 | ||
@@ -93,13 +86,13 @@ static DEFINE_PER_CPU(enum idle_state, idle_state) = CPU_NOT_IDLE; | |||
93 | void enter_idle(void) | 86 | void enter_idle(void) |
94 | { | 87 | { |
95 | __get_cpu_var(idle_state) = CPU_IDLE; | 88 | __get_cpu_var(idle_state) = CPU_IDLE; |
96 | notifier_call_chain(&idle_notifier, IDLE_START, NULL); | 89 | atomic_notifier_call_chain(&idle_notifier, IDLE_START, NULL); |
97 | } | 90 | } |
98 | 91 | ||
99 | static void __exit_idle(void) | 92 | static void __exit_idle(void) |
100 | { | 93 | { |
101 | __get_cpu_var(idle_state) = CPU_NOT_IDLE; | 94 | __get_cpu_var(idle_state) = CPU_NOT_IDLE; |
102 | notifier_call_chain(&idle_notifier, IDLE_END, NULL); | 95 | atomic_notifier_call_chain(&idle_notifier, IDLE_END, NULL); |
103 | } | 96 | } |
104 | 97 | ||
105 | /* Called from interrupts to signify idle end */ | 98 | /* Called from interrupts to signify idle end */ |
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 7b148309c529..edaa9fe654dc 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c | |||
@@ -69,20 +69,20 @@ asmlinkage void alignment_check(void); | |||
69 | asmlinkage void machine_check(void); | 69 | asmlinkage void machine_check(void); |
70 | asmlinkage void spurious_interrupt_bug(void); | 70 | asmlinkage void spurious_interrupt_bug(void); |
71 | 71 | ||
72 | struct notifier_block *die_chain; | 72 | ATOMIC_NOTIFIER_HEAD(die_chain); |
73 | static DEFINE_SPINLOCK(die_notifier_lock); | ||
74 | 73 | ||
75 | int register_die_notifier(struct notifier_block *nb) | 74 | int register_die_notifier(struct notifier_block *nb) |
76 | { | 75 | { |
77 | int err = 0; | ||
78 | unsigned long flags; | ||
79 | |||
80 | vmalloc_sync_all(); | 76 | vmalloc_sync_all(); |
81 | spin_lock_irqsave(&die_notifier_lock, flags); | 77 | return atomic_notifier_chain_register(&die_chain, nb); |
82 | err = notifier_chain_register(&die_chain, nb); | 78 | } |
83 | spin_unlock_irqrestore(&die_notifier_lock, flags); | 79 | EXPORT_SYMBOL(register_die_notifier); |
84 | return err; | 80 | |
81 | int unregister_die_notifier(struct notifier_block *nb) | ||
82 | { | ||
83 | return atomic_notifier_chain_unregister(&die_chain, nb); | ||
85 | } | 84 | } |
85 | EXPORT_SYMBOL(unregister_die_notifier); | ||
86 | 86 | ||
87 | static inline void conditional_sti(struct pt_regs *regs) | 87 | static inline void conditional_sti(struct pt_regs *regs) |
88 | { | 88 | { |
diff --git a/arch/xtensa/platform-iss/setup.c b/arch/xtensa/platform-iss/setup.c index 2e6dcbf0cc04..23790a5610e2 100644 --- a/arch/xtensa/platform-iss/setup.c +++ b/arch/xtensa/platform-iss/setup.c | |||
@@ -108,5 +108,5 @@ static struct notifier_block iss_panic_block = { | |||
108 | 108 | ||
109 | void __init platform_setup(char **p_cmdline) | 109 | void __init platform_setup(char **p_cmdline) |
110 | { | 110 | { |
111 | notifier_chain_register(&panic_notifier_list, &iss_panic_block); | 111 | atomic_notifier_chain_register(&panic_notifier_list, &iss_panic_block); |
112 | } | 112 | } |
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 105a0d61eb1f..dd547af4681a 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
@@ -47,16 +47,16 @@ static struct kset_uevent_ops memory_uevent_ops = { | |||
47 | .uevent = memory_uevent, | 47 | .uevent = memory_uevent, |
48 | }; | 48 | }; |
49 | 49 | ||
50 | static struct notifier_block *memory_chain; | 50 | static BLOCKING_NOTIFIER_HEAD(memory_chain); |
51 | 51 | ||
52 | int register_memory_notifier(struct notifier_block *nb) | 52 | int register_memory_notifier(struct notifier_block *nb) |
53 | { | 53 | { |
54 | return notifier_chain_register(&memory_chain, nb); | 54 | return blocking_notifier_chain_register(&memory_chain, nb); |
55 | } | 55 | } |
56 | 56 | ||
57 | void unregister_memory_notifier(struct notifier_block *nb) | 57 | void unregister_memory_notifier(struct notifier_block *nb) |
58 | { | 58 | { |
59 | notifier_chain_unregister(&memory_chain, nb); | 59 | blocking_notifier_chain_unregister(&memory_chain, nb); |
60 | } | 60 | } |
61 | 61 | ||
62 | /* | 62 | /* |
@@ -140,7 +140,7 @@ static ssize_t show_mem_state(struct sys_device *dev, char *buf) | |||
140 | 140 | ||
141 | static inline int memory_notify(unsigned long val, void *v) | 141 | static inline int memory_notify(unsigned long val, void *v) |
142 | { | 142 | { |
143 | return notifier_call_chain(&memory_chain, val, v); | 143 | return blocking_notifier_call_chain(&memory_chain, val, v); |
144 | } | 144 | } |
145 | 145 | ||
146 | /* | 146 | /* |
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index b8fb87c6c29f..40eb005b9d77 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -3744,7 +3744,7 @@ static int ipmi_init_msghandler(void) | |||
3744 | ipmi_timer.expires = jiffies + IPMI_TIMEOUT_JIFFIES; | 3744 | ipmi_timer.expires = jiffies + IPMI_TIMEOUT_JIFFIES; |
3745 | add_timer(&ipmi_timer); | 3745 | add_timer(&ipmi_timer); |
3746 | 3746 | ||
3747 | notifier_chain_register(&panic_notifier_list, &panic_block); | 3747 | atomic_notifier_chain_register(&panic_notifier_list, &panic_block); |
3748 | 3748 | ||
3749 | initialized = 1; | 3749 | initialized = 1; |
3750 | 3750 | ||
@@ -3764,7 +3764,7 @@ static __exit void cleanup_ipmi(void) | |||
3764 | if (!initialized) | 3764 | if (!initialized) |
3765 | return; | 3765 | return; |
3766 | 3766 | ||
3767 | notifier_chain_unregister(&panic_notifier_list, &panic_block); | 3767 | atomic_notifier_chain_unregister(&panic_notifier_list, &panic_block); |
3768 | 3768 | ||
3769 | /* This can't be called if any interfaces exist, so no worry about | 3769 | /* This can't be called if any interfaces exist, so no worry about |
3770 | shutting down the interfaces. */ | 3770 | shutting down the interfaces. */ |
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 12f858dc9994..35fbd4d8ed4b 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -237,10 +237,10 @@ struct smi_info | |||
237 | 237 | ||
238 | static int try_smi_init(struct smi_info *smi); | 238 | static int try_smi_init(struct smi_info *smi); |
239 | 239 | ||
240 | static struct notifier_block *xaction_notifier_list; | 240 | static ATOMIC_NOTIFIER_HEAD(xaction_notifier_list); |
241 | static int register_xaction_notifier(struct notifier_block * nb) | 241 | static int register_xaction_notifier(struct notifier_block * nb) |
242 | { | 242 | { |
243 | return notifier_chain_register(&xaction_notifier_list, nb); | 243 | return atomic_notifier_chain_register(&xaction_notifier_list, nb); |
244 | } | 244 | } |
245 | 245 | ||
246 | static void si_restart_short_timer(struct smi_info *smi_info); | 246 | static void si_restart_short_timer(struct smi_info *smi_info); |
@@ -302,7 +302,8 @@ static enum si_sm_result start_next_msg(struct smi_info *smi_info) | |||
302 | do_gettimeofday(&t); | 302 | do_gettimeofday(&t); |
303 | printk("**Start2: %d.%9.9d\n", t.tv_sec, t.tv_usec); | 303 | printk("**Start2: %d.%9.9d\n", t.tv_sec, t.tv_usec); |
304 | #endif | 304 | #endif |
305 | err = notifier_call_chain(&xaction_notifier_list, 0, smi_info); | 305 | err = atomic_notifier_call_chain(&xaction_notifier_list, |
306 | 0, smi_info); | ||
306 | if (err & NOTIFY_STOP_MASK) { | 307 | if (err & NOTIFY_STOP_MASK) { |
307 | rv = SI_SM_CALL_WITHOUT_DELAY; | 308 | rv = SI_SM_CALL_WITHOUT_DELAY; |
308 | goto out; | 309 | goto out; |
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index 616539310d9a..7ece9f3c8f70 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c | |||
@@ -1158,7 +1158,8 @@ static int __init ipmi_wdog_init(void) | |||
1158 | } | 1158 | } |
1159 | 1159 | ||
1160 | register_reboot_notifier(&wdog_reboot_notifier); | 1160 | register_reboot_notifier(&wdog_reboot_notifier); |
1161 | notifier_chain_register(&panic_notifier_list, &wdog_panic_notifier); | 1161 | atomic_notifier_chain_register(&panic_notifier_list, |
1162 | &wdog_panic_notifier); | ||
1162 | 1163 | ||
1163 | printk(KERN_INFO PFX "driver initialized\n"); | 1164 | printk(KERN_INFO PFX "driver initialized\n"); |
1164 | 1165 | ||
@@ -1176,7 +1177,8 @@ static __exit void ipmi_unregister_watchdog(void) | |||
1176 | release_nmi(&ipmi_nmi_handler); | 1177 | release_nmi(&ipmi_nmi_handler); |
1177 | #endif | 1178 | #endif |
1178 | 1179 | ||
1179 | notifier_chain_unregister(&panic_notifier_list, &wdog_panic_notifier); | 1180 | atomic_notifier_chain_unregister(&panic_notifier_list, |
1181 | &wdog_panic_notifier); | ||
1180 | unregister_reboot_notifier(&wdog_reboot_notifier); | 1182 | unregister_reboot_notifier(&wdog_reboot_notifier); |
1181 | 1183 | ||
1182 | if (! watchdog_user) | 1184 | if (! watchdog_user) |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index aed80e6aec6d..9b6ae7dc8b8a 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -52,9 +52,8 @@ static void handle_update(void *data); | |||
52 | * changes to devices when the CPU clock speed changes. | 52 | * changes to devices when the CPU clock speed changes. |
53 | * The mutex locks both lists. | 53 | * The mutex locks both lists. |
54 | */ | 54 | */ |
55 | static struct notifier_block *cpufreq_policy_notifier_list; | 55 | static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list); |
56 | static struct notifier_block *cpufreq_transition_notifier_list; | 56 | static BLOCKING_NOTIFIER_HEAD(cpufreq_transition_notifier_list); |
57 | static DECLARE_RWSEM (cpufreq_notifier_rwsem); | ||
58 | 57 | ||
59 | 58 | ||
60 | static LIST_HEAD(cpufreq_governor_list); | 59 | static LIST_HEAD(cpufreq_governor_list); |
@@ -247,8 +246,6 @@ void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state) | |||
247 | dprintk("notification %u of frequency transition to %u kHz\n", | 246 | dprintk("notification %u of frequency transition to %u kHz\n", |
248 | state, freqs->new); | 247 | state, freqs->new); |
249 | 248 | ||
250 | down_read(&cpufreq_notifier_rwsem); | ||
251 | |||
252 | policy = cpufreq_cpu_data[freqs->cpu]; | 249 | policy = cpufreq_cpu_data[freqs->cpu]; |
253 | switch (state) { | 250 | switch (state) { |
254 | 251 | ||
@@ -266,20 +263,19 @@ void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state) | |||
266 | freqs->old = policy->cur; | 263 | freqs->old = policy->cur; |
267 | } | 264 | } |
268 | } | 265 | } |
269 | notifier_call_chain(&cpufreq_transition_notifier_list, | 266 | blocking_notifier_call_chain(&cpufreq_transition_notifier_list, |
270 | CPUFREQ_PRECHANGE, freqs); | 267 | CPUFREQ_PRECHANGE, freqs); |
271 | adjust_jiffies(CPUFREQ_PRECHANGE, freqs); | 268 | adjust_jiffies(CPUFREQ_PRECHANGE, freqs); |
272 | break; | 269 | break; |
273 | 270 | ||
274 | case CPUFREQ_POSTCHANGE: | 271 | case CPUFREQ_POSTCHANGE: |
275 | adjust_jiffies(CPUFREQ_POSTCHANGE, freqs); | 272 | adjust_jiffies(CPUFREQ_POSTCHANGE, freqs); |
276 | notifier_call_chain(&cpufreq_transition_notifier_list, | 273 | blocking_notifier_call_chain(&cpufreq_transition_notifier_list, |
277 | CPUFREQ_POSTCHANGE, freqs); | 274 | CPUFREQ_POSTCHANGE, freqs); |
278 | if (likely(policy) && likely(policy->cpu == freqs->cpu)) | 275 | if (likely(policy) && likely(policy->cpu == freqs->cpu)) |
279 | policy->cur = freqs->new; | 276 | policy->cur = freqs->new; |
280 | break; | 277 | break; |
281 | } | 278 | } |
282 | up_read(&cpufreq_notifier_rwsem); | ||
283 | } | 279 | } |
284 | EXPORT_SYMBOL_GPL(cpufreq_notify_transition); | 280 | EXPORT_SYMBOL_GPL(cpufreq_notify_transition); |
285 | 281 | ||
@@ -1007,7 +1003,7 @@ static int cpufreq_suspend(struct sys_device * sysdev, pm_message_t pmsg) | |||
1007 | freqs.old = cpu_policy->cur; | 1003 | freqs.old = cpu_policy->cur; |
1008 | freqs.new = cur_freq; | 1004 | freqs.new = cur_freq; |
1009 | 1005 | ||
1010 | notifier_call_chain(&cpufreq_transition_notifier_list, | 1006 | blocking_notifier_call_chain(&cpufreq_transition_notifier_list, |
1011 | CPUFREQ_SUSPENDCHANGE, &freqs); | 1007 | CPUFREQ_SUSPENDCHANGE, &freqs); |
1012 | adjust_jiffies(CPUFREQ_SUSPENDCHANGE, &freqs); | 1008 | adjust_jiffies(CPUFREQ_SUSPENDCHANGE, &freqs); |
1013 | 1009 | ||
@@ -1088,7 +1084,8 @@ static int cpufreq_resume(struct sys_device * sysdev) | |||
1088 | freqs.old = cpu_policy->cur; | 1084 | freqs.old = cpu_policy->cur; |
1089 | freqs.new = cur_freq; | 1085 | freqs.new = cur_freq; |
1090 | 1086 | ||
1091 | notifier_call_chain(&cpufreq_transition_notifier_list, | 1087 | blocking_notifier_call_chain( |
1088 | &cpufreq_transition_notifier_list, | ||
1092 | CPUFREQ_RESUMECHANGE, &freqs); | 1089 | CPUFREQ_RESUMECHANGE, &freqs); |
1093 | adjust_jiffies(CPUFREQ_RESUMECHANGE, &freqs); | 1090 | adjust_jiffies(CPUFREQ_RESUMECHANGE, &freqs); |
1094 | 1091 | ||
@@ -1125,24 +1122,24 @@ static struct sysdev_driver cpufreq_sysdev_driver = { | |||
1125 | * changes in cpufreq policy. | 1122 | * changes in cpufreq policy. |
1126 | * | 1123 | * |
1127 | * This function may sleep, and has the same return conditions as | 1124 | * This function may sleep, and has the same return conditions as |
1128 | * notifier_chain_register. | 1125 | * blocking_notifier_chain_register. |
1129 | */ | 1126 | */ |
1130 | int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list) | 1127 | int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list) |
1131 | { | 1128 | { |
1132 | int ret; | 1129 | int ret; |
1133 | 1130 | ||
1134 | down_write(&cpufreq_notifier_rwsem); | ||
1135 | switch (list) { | 1131 | switch (list) { |
1136 | case CPUFREQ_TRANSITION_NOTIFIER: | 1132 | case CPUFREQ_TRANSITION_NOTIFIER: |
1137 | ret = notifier_chain_register(&cpufreq_transition_notifier_list, nb); | 1133 | ret = blocking_notifier_chain_register( |
1134 | &cpufreq_transition_notifier_list, nb); | ||
1138 | break; | 1135 | break; |
1139 | case CPUFREQ_POLICY_NOTIFIER: | 1136 | case CPUFREQ_POLICY_NOTIFIER: |
1140 | ret = notifier_chain_register(&cpufreq_policy_notifier_list, nb); | 1137 | ret = blocking_notifier_chain_register( |
1138 | &cpufreq_policy_notifier_list, nb); | ||
1141 | break; | 1139 | break; |
1142 | default: | 1140 | default: |
1143 | ret = -EINVAL; | 1141 | ret = -EINVAL; |
1144 | } | 1142 | } |
1145 | up_write(&cpufreq_notifier_rwsem); | ||
1146 | 1143 | ||
1147 | return ret; | 1144 | return ret; |
1148 | } | 1145 | } |
@@ -1157,24 +1154,24 @@ EXPORT_SYMBOL(cpufreq_register_notifier); | |||
1157 | * Remove a driver from the CPU frequency notifier list. | 1154 | * Remove a driver from the CPU frequency notifier list. |
1158 | * | 1155 | * |
1159 | * This function may sleep, and has the same return conditions as | 1156 | * This function may sleep, and has the same return conditions as |
1160 | * notifier_chain_unregister. | 1157 | * blocking_notifier_chain_unregister. |
1161 | */ | 1158 | */ |
1162 | int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list) | 1159 | int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list) |
1163 | { | 1160 | { |
1164 | int ret; | 1161 | int ret; |
1165 | 1162 | ||
1166 | down_write(&cpufreq_notifier_rwsem); | ||
1167 | switch (list) { | 1163 | switch (list) { |
1168 | case CPUFREQ_TRANSITION_NOTIFIER: | 1164 | case CPUFREQ_TRANSITION_NOTIFIER: |
1169 | ret = notifier_chain_unregister(&cpufreq_transition_notifier_list, nb); | 1165 | ret = blocking_notifier_chain_unregister( |
1166 | &cpufreq_transition_notifier_list, nb); | ||
1170 | break; | 1167 | break; |
1171 | case CPUFREQ_POLICY_NOTIFIER: | 1168 | case CPUFREQ_POLICY_NOTIFIER: |
1172 | ret = notifier_chain_unregister(&cpufreq_policy_notifier_list, nb); | 1169 | ret = blocking_notifier_chain_unregister( |
1170 | &cpufreq_policy_notifier_list, nb); | ||
1173 | break; | 1171 | break; |
1174 | default: | 1172 | default: |
1175 | ret = -EINVAL; | 1173 | ret = -EINVAL; |
1176 | } | 1174 | } |
1177 | up_write(&cpufreq_notifier_rwsem); | ||
1178 | 1175 | ||
1179 | return ret; | 1176 | return ret; |
1180 | } | 1177 | } |
@@ -1346,29 +1343,23 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_poli | |||
1346 | if (ret) | 1343 | if (ret) |
1347 | goto error_out; | 1344 | goto error_out; |
1348 | 1345 | ||
1349 | down_read(&cpufreq_notifier_rwsem); | ||
1350 | |||
1351 | /* adjust if necessary - all reasons */ | 1346 | /* adjust if necessary - all reasons */ |
1352 | notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_ADJUST, | 1347 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, |
1353 | policy); | 1348 | CPUFREQ_ADJUST, policy); |
1354 | 1349 | ||
1355 | /* adjust if necessary - hardware incompatibility*/ | 1350 | /* adjust if necessary - hardware incompatibility*/ |
1356 | notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_INCOMPATIBLE, | 1351 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, |
1357 | policy); | 1352 | CPUFREQ_INCOMPATIBLE, policy); |
1358 | 1353 | ||
1359 | /* verify the cpu speed can be set within this limit, | 1354 | /* verify the cpu speed can be set within this limit, |
1360 | which might be different to the first one */ | 1355 | which might be different to the first one */ |
1361 | ret = cpufreq_driver->verify(policy); | 1356 | ret = cpufreq_driver->verify(policy); |
1362 | if (ret) { | 1357 | if (ret) |
1363 | up_read(&cpufreq_notifier_rwsem); | ||
1364 | goto error_out; | 1358 | goto error_out; |
1365 | } | ||
1366 | 1359 | ||
1367 | /* notification of the new policy */ | 1360 | /* notification of the new policy */ |
1368 | notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_NOTIFY, | 1361 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, |
1369 | policy); | 1362 | CPUFREQ_NOTIFY, policy); |
1370 | |||
1371 | up_read(&cpufreq_notifier_rwsem); | ||
1372 | 1363 | ||
1373 | data->min = policy->min; | 1364 | data->min = policy->min; |
1374 | data->max = policy->max; | 1365 | data->max = policy->max; |
diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c index d6543fc4a923..339f405ff708 100644 --- a/drivers/firmware/dcdbas.c +++ b/drivers/firmware/dcdbas.c | |||
@@ -484,26 +484,15 @@ static void dcdbas_host_control(void) | |||
484 | static int dcdbas_reboot_notify(struct notifier_block *nb, unsigned long code, | 484 | static int dcdbas_reboot_notify(struct notifier_block *nb, unsigned long code, |
485 | void *unused) | 485 | void *unused) |
486 | { | 486 | { |
487 | static unsigned int notify_cnt = 0; | ||
488 | |||
489 | switch (code) { | 487 | switch (code) { |
490 | case SYS_DOWN: | 488 | case SYS_DOWN: |
491 | case SYS_HALT: | 489 | case SYS_HALT: |
492 | case SYS_POWER_OFF: | 490 | case SYS_POWER_OFF: |
493 | if (host_control_on_shutdown) { | 491 | if (host_control_on_shutdown) { |
494 | /* firmware is going to perform host control action */ | 492 | /* firmware is going to perform host control action */ |
495 | if (++notify_cnt == 2) { | 493 | printk(KERN_WARNING "Please wait for shutdown " |
496 | printk(KERN_WARNING | 494 | "action to complete...\n"); |
497 | "Please wait for shutdown " | 495 | dcdbas_host_control(); |
498 | "action to complete...\n"); | ||
499 | dcdbas_host_control(); | ||
500 | } | ||
501 | /* | ||
502 | * register again and initiate the host control | ||
503 | * action on the second notification to allow | ||
504 | * everyone that registered to be notified | ||
505 | */ | ||
506 | register_reboot_notifier(nb); | ||
507 | } | 496 | } |
508 | break; | 497 | break; |
509 | } | 498 | } |
@@ -514,7 +503,7 @@ static int dcdbas_reboot_notify(struct notifier_block *nb, unsigned long code, | |||
514 | static struct notifier_block dcdbas_reboot_nb = { | 503 | static struct notifier_block dcdbas_reboot_nb = { |
515 | .notifier_call = dcdbas_reboot_notify, | 504 | .notifier_call = dcdbas_reboot_notify, |
516 | .next = NULL, | 505 | .next = NULL, |
517 | .priority = 0 | 506 | .priority = INT_MIN |
518 | }; | 507 | }; |
519 | 508 | ||
520 | static DCDBAS_BIN_ATTR_RW(smi_data); | 509 | static DCDBAS_BIN_ATTR_RW(smi_data); |
diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c index d2ead1776c16..34fcabac5fdb 100644 --- a/drivers/macintosh/adb.c +++ b/drivers/macintosh/adb.c | |||
@@ -80,7 +80,7 @@ static struct adb_driver *adb_driver_list[] = { | |||
80 | static struct class *adb_dev_class; | 80 | static struct class *adb_dev_class; |
81 | 81 | ||
82 | struct adb_driver *adb_controller; | 82 | struct adb_driver *adb_controller; |
83 | struct notifier_block *adb_client_list = NULL; | 83 | BLOCKING_NOTIFIER_HEAD(adb_client_list); |
84 | static int adb_got_sleep; | 84 | static int adb_got_sleep; |
85 | static int adb_inited; | 85 | static int adb_inited; |
86 | static pid_t adb_probe_task_pid; | 86 | static pid_t adb_probe_task_pid; |
@@ -354,7 +354,8 @@ adb_notify_sleep(struct pmu_sleep_notifier *self, int when) | |||
354 | /* Stop autopoll */ | 354 | /* Stop autopoll */ |
355 | if (adb_controller->autopoll) | 355 | if (adb_controller->autopoll) |
356 | adb_controller->autopoll(0); | 356 | adb_controller->autopoll(0); |
357 | ret = notifier_call_chain(&adb_client_list, ADB_MSG_POWERDOWN, NULL); | 357 | ret = blocking_notifier_call_chain(&adb_client_list, |
358 | ADB_MSG_POWERDOWN, NULL); | ||
358 | if (ret & NOTIFY_STOP_MASK) { | 359 | if (ret & NOTIFY_STOP_MASK) { |
359 | up(&adb_probe_mutex); | 360 | up(&adb_probe_mutex); |
360 | return PBOOK_SLEEP_REFUSE; | 361 | return PBOOK_SLEEP_REFUSE; |
@@ -391,7 +392,8 @@ do_adb_reset_bus(void) | |||
391 | if (adb_controller->autopoll) | 392 | if (adb_controller->autopoll) |
392 | adb_controller->autopoll(0); | 393 | adb_controller->autopoll(0); |
393 | 394 | ||
394 | nret = notifier_call_chain(&adb_client_list, ADB_MSG_PRE_RESET, NULL); | 395 | nret = blocking_notifier_call_chain(&adb_client_list, |
396 | ADB_MSG_PRE_RESET, NULL); | ||
395 | if (nret & NOTIFY_STOP_MASK) { | 397 | if (nret & NOTIFY_STOP_MASK) { |
396 | if (adb_controller->autopoll) | 398 | if (adb_controller->autopoll) |
397 | adb_controller->autopoll(autopoll_devs); | 399 | adb_controller->autopoll(autopoll_devs); |
@@ -426,7 +428,8 @@ do_adb_reset_bus(void) | |||
426 | } | 428 | } |
427 | up(&adb_handler_sem); | 429 | up(&adb_handler_sem); |
428 | 430 | ||
429 | nret = notifier_call_chain(&adb_client_list, ADB_MSG_POST_RESET, NULL); | 431 | nret = blocking_notifier_call_chain(&adb_client_list, |
432 | ADB_MSG_POST_RESET, NULL); | ||
430 | if (nret & NOTIFY_STOP_MASK) | 433 | if (nret & NOTIFY_STOP_MASK) |
431 | return -EBUSY; | 434 | return -EBUSY; |
432 | 435 | ||
diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c index c0b46bceb5df..f5779a73184d 100644 --- a/drivers/macintosh/adbhid.c +++ b/drivers/macintosh/adbhid.c | |||
@@ -1214,7 +1214,8 @@ static int __init adbhid_init(void) | |||
1214 | 1214 | ||
1215 | adbhid_probe(); | 1215 | adbhid_probe(); |
1216 | 1216 | ||
1217 | notifier_chain_register(&adb_client_list, &adbhid_adb_notifier); | 1217 | blocking_notifier_chain_register(&adb_client_list, |
1218 | &adbhid_adb_notifier); | ||
1218 | 1219 | ||
1219 | return 0; | 1220 | return 0; |
1220 | } | 1221 | } |
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index 4f5f3abc9cb3..0b5ff553e39a 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c | |||
@@ -187,7 +187,7 @@ extern int disable_kernel_backlight; | |||
187 | 187 | ||
188 | int __fake_sleep; | 188 | int __fake_sleep; |
189 | int asleep; | 189 | int asleep; |
190 | struct notifier_block *sleep_notifier_list; | 190 | BLOCKING_NOTIFIER_HEAD(sleep_notifier_list); |
191 | 191 | ||
192 | #ifdef CONFIG_ADB | 192 | #ifdef CONFIG_ADB |
193 | static int adb_dev_map = 0; | 193 | static int adb_dev_map = 0; |
diff --git a/drivers/macintosh/via-pmu68k.c b/drivers/macintosh/via-pmu68k.c index f08e52f2107b..35b70323e7e3 100644 --- a/drivers/macintosh/via-pmu68k.c +++ b/drivers/macintosh/via-pmu68k.c | |||
@@ -102,7 +102,7 @@ static int pmu_kind = PMU_UNKNOWN; | |||
102 | static int pmu_fully_inited = 0; | 102 | static int pmu_fully_inited = 0; |
103 | 103 | ||
104 | int asleep; | 104 | int asleep; |
105 | struct notifier_block *sleep_notifier_list; | 105 | BLOCKING_NOTIFIER_HEAD(sleep_notifier_list); |
106 | 106 | ||
107 | static int pmu_probe(void); | 107 | static int pmu_probe(void); |
108 | static int pmu_init(void); | 108 | static int pmu_init(void); |
@@ -913,7 +913,8 @@ int powerbook_sleep(void) | |||
913 | struct adb_request sleep_req; | 913 | struct adb_request sleep_req; |
914 | 914 | ||
915 | /* Notify device drivers */ | 915 | /* Notify device drivers */ |
916 | ret = notifier_call_chain(&sleep_notifier_list, PBOOK_SLEEP, NULL); | 916 | ret = blocking_notifier_call_chain(&sleep_notifier_list, |
917 | PBOOK_SLEEP, NULL); | ||
917 | if (ret & NOTIFY_STOP_MASK) | 918 | if (ret & NOTIFY_STOP_MASK) |
918 | return -EBUSY; | 919 | return -EBUSY; |
919 | 920 | ||
@@ -984,7 +985,7 @@ int powerbook_sleep(void) | |||
984 | enable_irq(i); | 985 | enable_irq(i); |
985 | 986 | ||
986 | /* Notify drivers */ | 987 | /* Notify drivers */ |
987 | notifier_call_chain(&sleep_notifier_list, PBOOK_WAKE, NULL); | 988 | blocking_notifier_call_chain(&sleep_notifier_list, PBOOK_WAKE, NULL); |
988 | 989 | ||
989 | /* reenable ADB autopoll */ | 990 | /* reenable ADB autopoll */ |
990 | pmu_adb_autopoll(adb_dev_map); | 991 | pmu_adb_autopoll(adb_dev_map); |
diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c index 6c0ba04bc57a..ab3faa702d58 100644 --- a/drivers/macintosh/windfarm_core.c +++ b/drivers/macintosh/windfarm_core.c | |||
@@ -52,7 +52,7 @@ | |||
52 | static LIST_HEAD(wf_controls); | 52 | static LIST_HEAD(wf_controls); |
53 | static LIST_HEAD(wf_sensors); | 53 | static LIST_HEAD(wf_sensors); |
54 | static DEFINE_MUTEX(wf_lock); | 54 | static DEFINE_MUTEX(wf_lock); |
55 | static struct notifier_block *wf_client_list; | 55 | static BLOCKING_NOTIFIER_HEAD(wf_client_list); |
56 | static int wf_client_count; | 56 | static int wf_client_count; |
57 | static unsigned int wf_overtemp; | 57 | static unsigned int wf_overtemp; |
58 | static unsigned int wf_overtemp_counter; | 58 | static unsigned int wf_overtemp_counter; |
@@ -68,7 +68,7 @@ static struct platform_device wf_platform_device = { | |||
68 | 68 | ||
69 | static inline void wf_notify(int event, void *param) | 69 | static inline void wf_notify(int event, void *param) |
70 | { | 70 | { |
71 | notifier_call_chain(&wf_client_list, event, param); | 71 | blocking_notifier_call_chain(&wf_client_list, event, param); |
72 | } | 72 | } |
73 | 73 | ||
74 | int wf_critical_overtemp(void) | 74 | int wf_critical_overtemp(void) |
@@ -398,7 +398,7 @@ int wf_register_client(struct notifier_block *nb) | |||
398 | struct wf_sensor *sr; | 398 | struct wf_sensor *sr; |
399 | 399 | ||
400 | mutex_lock(&wf_lock); | 400 | mutex_lock(&wf_lock); |
401 | rc = notifier_chain_register(&wf_client_list, nb); | 401 | rc = blocking_notifier_chain_register(&wf_client_list, nb); |
402 | if (rc != 0) | 402 | if (rc != 0) |
403 | goto bail; | 403 | goto bail; |
404 | wf_client_count++; | 404 | wf_client_count++; |
@@ -417,7 +417,7 @@ EXPORT_SYMBOL_GPL(wf_register_client); | |||
417 | int wf_unregister_client(struct notifier_block *nb) | 417 | int wf_unregister_client(struct notifier_block *nb) |
418 | { | 418 | { |
419 | mutex_lock(&wf_lock); | 419 | mutex_lock(&wf_lock); |
420 | notifier_chain_unregister(&wf_client_list, nb); | 420 | blocking_notifier_chain_unregister(&wf_client_list, nb); |
421 | wf_client_count++; | 421 | wf_client_count++; |
422 | if (wf_client_count == 0) | 422 | if (wf_client_count == 0) |
423 | wf_stop_thread(); | 423 | wf_stop_thread(); |
diff --git a/drivers/misc/ibmasm/heartbeat.c b/drivers/misc/ibmasm/heartbeat.c index f295401fac21..7fd7a43e38de 100644 --- a/drivers/misc/ibmasm/heartbeat.c +++ b/drivers/misc/ibmasm/heartbeat.c | |||
@@ -52,12 +52,13 @@ static struct notifier_block panic_notifier = { panic_happened, NULL, 1 }; | |||
52 | 52 | ||
53 | void ibmasm_register_panic_notifier(void) | 53 | void ibmasm_register_panic_notifier(void) |
54 | { | 54 | { |
55 | notifier_chain_register(&panic_notifier_list, &panic_notifier); | 55 | atomic_notifier_chain_register(&panic_notifier_list, &panic_notifier); |
56 | } | 56 | } |
57 | 57 | ||
58 | void ibmasm_unregister_panic_notifier(void) | 58 | void ibmasm_unregister_panic_notifier(void) |
59 | { | 59 | { |
60 | notifier_chain_unregister(&panic_notifier_list, &panic_notifier); | 60 | atomic_notifier_chain_unregister(&panic_notifier_list, |
61 | &panic_notifier); | ||
61 | } | 62 | } |
62 | 63 | ||
63 | 64 | ||
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 2d0ac169a86c..f13a539dc169 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -3159,7 +3159,7 @@ static int bond_slave_netdev_event(unsigned long event, struct net_device *slave | |||
3159 | * bond_netdev_event: handle netdev notifier chain events. | 3159 | * bond_netdev_event: handle netdev notifier chain events. |
3160 | * | 3160 | * |
3161 | * This function receives events for the netdev chain. The caller (an | 3161 | * This function receives events for the netdev chain. The caller (an |
3162 | * ioctl handler calling notifier_call_chain) holds the necessary | 3162 | * ioctl handler calling blocking_notifier_call_chain) holds the necessary |
3163 | * locks for us to safely manipulate the slave devices (RTNL lock, | 3163 | * locks for us to safely manipulate the slave devices (RTNL lock, |
3164 | * dev_probe_lock). | 3164 | * dev_probe_lock). |
3165 | */ | 3165 | */ |
diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c index 3627a2d7f79f..298f2ddb2c17 100644 --- a/drivers/parisc/led.c +++ b/drivers/parisc/led.c | |||
@@ -499,11 +499,16 @@ static int led_halt(struct notifier_block *, unsigned long, void *); | |||
499 | static struct notifier_block led_notifier = { | 499 | static struct notifier_block led_notifier = { |
500 | .notifier_call = led_halt, | 500 | .notifier_call = led_halt, |
501 | }; | 501 | }; |
502 | static int notifier_disabled = 0; | ||
502 | 503 | ||
503 | static int led_halt(struct notifier_block *nb, unsigned long event, void *buf) | 504 | static int led_halt(struct notifier_block *nb, unsigned long event, void *buf) |
504 | { | 505 | { |
505 | char *txt; | 506 | char *txt; |
506 | 507 | ||
508 | if (notifier_disabled) | ||
509 | return NOTIFY_OK; | ||
510 | |||
511 | notifier_disabled = 1; | ||
507 | switch (event) { | 512 | switch (event) { |
508 | case SYS_RESTART: txt = "SYSTEM RESTART"; | 513 | case SYS_RESTART: txt = "SYSTEM RESTART"; |
509 | break; | 514 | break; |
@@ -527,7 +532,6 @@ static int led_halt(struct notifier_block *nb, unsigned long event, void *buf) | |||
527 | if (led_func_ptr) | 532 | if (led_func_ptr) |
528 | led_func_ptr(0xff); /* turn all LEDs ON */ | 533 | led_func_ptr(0xff); /* turn all LEDs ON */ |
529 | 534 | ||
530 | unregister_reboot_notifier(&led_notifier); | ||
531 | return NOTIFY_OK; | 535 | return NOTIFY_OK; |
532 | } | 536 | } |
533 | 537 | ||
@@ -758,6 +762,12 @@ not_found: | |||
758 | return 1; | 762 | return 1; |
759 | } | 763 | } |
760 | 764 | ||
765 | static void __exit led_exit(void) | ||
766 | { | ||
767 | unregister_reboot_notifier(&led_notifier); | ||
768 | return; | ||
769 | } | ||
770 | |||
761 | #ifdef CONFIG_PROC_FS | 771 | #ifdef CONFIG_PROC_FS |
762 | module_init(led_create_procfs) | 772 | module_init(led_create_procfs) |
763 | #endif | 773 | #endif |
diff --git a/drivers/parisc/power.c b/drivers/parisc/power.c index 54b2b7f20b96..0bcab83b4080 100644 --- a/drivers/parisc/power.c +++ b/drivers/parisc/power.c | |||
@@ -251,7 +251,8 @@ static int __init power_init(void) | |||
251 | } | 251 | } |
252 | 252 | ||
253 | /* Register a call for panic conditions. */ | 253 | /* Register a call for panic conditions. */ |
254 | notifier_chain_register(&panic_notifier_list, &parisc_panic_block); | 254 | atomic_notifier_chain_register(&panic_notifier_list, |
255 | &parisc_panic_block); | ||
255 | 256 | ||
256 | tasklet_enable(&power_tasklet); | 257 | tasklet_enable(&power_tasklet); |
257 | 258 | ||
@@ -264,7 +265,8 @@ static void __exit power_exit(void) | |||
264 | return; | 265 | return; |
265 | 266 | ||
266 | tasklet_disable(&power_tasklet); | 267 | tasklet_disable(&power_tasklet); |
267 | notifier_chain_unregister(&panic_notifier_list, &parisc_panic_block); | 268 | atomic_notifier_chain_unregister(&panic_notifier_list, |
269 | &parisc_panic_block); | ||
268 | power_tasklet.func = NULL; | 270 | power_tasklet.func = NULL; |
269 | pdc_soft_power_button(0); | 271 | pdc_soft_power_button(0); |
270 | } | 272 | } |
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index 62e3cda859af..7f7013e80a88 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c | |||
@@ -671,7 +671,7 @@ static struct file_operations gdth_fops = { | |||
671 | static struct notifier_block gdth_notifier = { | 671 | static struct notifier_block gdth_notifier = { |
672 | gdth_halt, NULL, 0 | 672 | gdth_halt, NULL, 0 |
673 | }; | 673 | }; |
674 | 674 | static int notifier_disabled = 0; | |
675 | 675 | ||
676 | static void gdth_delay(int milliseconds) | 676 | static void gdth_delay(int milliseconds) |
677 | { | 677 | { |
@@ -4595,13 +4595,13 @@ static int __init gdth_detect(struct scsi_host_template *shtp) | |||
4595 | add_timer(&gdth_timer); | 4595 | add_timer(&gdth_timer); |
4596 | #endif | 4596 | #endif |
4597 | major = register_chrdev(0,"gdth",&gdth_fops); | 4597 | major = register_chrdev(0,"gdth",&gdth_fops); |
4598 | notifier_disabled = 0; | ||
4598 | register_reboot_notifier(&gdth_notifier); | 4599 | register_reboot_notifier(&gdth_notifier); |
4599 | } | 4600 | } |
4600 | gdth_polling = FALSE; | 4601 | gdth_polling = FALSE; |
4601 | return gdth_ctr_vcount; | 4602 | return gdth_ctr_vcount; |
4602 | } | 4603 | } |
4603 | 4604 | ||
4604 | |||
4605 | static int gdth_release(struct Scsi_Host *shp) | 4605 | static int gdth_release(struct Scsi_Host *shp) |
4606 | { | 4606 | { |
4607 | int hanum; | 4607 | int hanum; |
@@ -5632,10 +5632,14 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) | |||
5632 | char cmnd[MAX_COMMAND_SIZE]; | 5632 | char cmnd[MAX_COMMAND_SIZE]; |
5633 | #endif | 5633 | #endif |
5634 | 5634 | ||
5635 | if (notifier_disabled) | ||
5636 | return NOTIFY_OK; | ||
5637 | |||
5635 | TRACE2(("gdth_halt() event %d\n",(int)event)); | 5638 | TRACE2(("gdth_halt() event %d\n",(int)event)); |
5636 | if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF) | 5639 | if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF) |
5637 | return NOTIFY_DONE; | 5640 | return NOTIFY_DONE; |
5638 | 5641 | ||
5642 | notifier_disabled = 1; | ||
5639 | printk("GDT-HA: Flushing all host drives .. "); | 5643 | printk("GDT-HA: Flushing all host drives .. "); |
5640 | for (hanum = 0; hanum < gdth_ctr_count; ++hanum) { | 5644 | for (hanum = 0; hanum < gdth_ctr_count; ++hanum) { |
5641 | gdth_flush(hanum); | 5645 | gdth_flush(hanum); |
@@ -5679,7 +5683,6 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) | |||
5679 | #ifdef GDTH_STATISTICS | 5683 | #ifdef GDTH_STATISTICS |
5680 | del_timer(&gdth_timer); | 5684 | del_timer(&gdth_timer); |
5681 | #endif | 5685 | #endif |
5682 | unregister_reboot_notifier(&gdth_notifier); | ||
5683 | return NOTIFY_OK; | 5686 | return NOTIFY_OK; |
5684 | } | 5687 | } |
5685 | 5688 | ||
diff --git a/drivers/usb/core/notify.c b/drivers/usb/core/notify.c index 4b55285de9a0..fe0ed54fa0ae 100644 --- a/drivers/usb/core/notify.c +++ b/drivers/usb/core/notify.c | |||
@@ -16,57 +16,7 @@ | |||
16 | #include <linux/mutex.h> | 16 | #include <linux/mutex.h> |
17 | #include "usb.h" | 17 | #include "usb.h" |
18 | 18 | ||
19 | 19 | static BLOCKING_NOTIFIER_HEAD(usb_notifier_list); | |
20 | static struct notifier_block *usb_notifier_list; | ||
21 | static DEFINE_MUTEX(usb_notifier_lock); | ||
22 | |||
23 | static void usb_notifier_chain_register(struct notifier_block **list, | ||
24 | struct notifier_block *n) | ||
25 | { | ||
26 | mutex_lock(&usb_notifier_lock); | ||
27 | while (*list) { | ||
28 | if (n->priority > (*list)->priority) | ||
29 | break; | ||
30 | list = &((*list)->next); | ||
31 | } | ||
32 | n->next = *list; | ||
33 | *list = n; | ||
34 | mutex_unlock(&usb_notifier_lock); | ||
35 | } | ||
36 | |||
37 | static void usb_notifier_chain_unregister(struct notifier_block **nl, | ||
38 | struct notifier_block *n) | ||
39 | { | ||
40 | mutex_lock(&usb_notifier_lock); | ||
41 | while ((*nl)!=NULL) { | ||
42 | if ((*nl)==n) { | ||
43 | *nl = n->next; | ||
44 | goto exit; | ||
45 | } | ||
46 | nl=&((*nl)->next); | ||
47 | } | ||
48 | exit: | ||
49 | mutex_unlock(&usb_notifier_lock); | ||
50 | } | ||
51 | |||
52 | static int usb_notifier_call_chain(struct notifier_block **n, | ||
53 | unsigned long val, void *v) | ||
54 | { | ||
55 | int ret=NOTIFY_DONE; | ||
56 | struct notifier_block *nb = *n; | ||
57 | |||
58 | mutex_lock(&usb_notifier_lock); | ||
59 | while (nb) { | ||
60 | ret = nb->notifier_call(nb,val,v); | ||
61 | if (ret&NOTIFY_STOP_MASK) { | ||
62 | goto exit; | ||
63 | } | ||
64 | nb = nb->next; | ||
65 | } | ||
66 | exit: | ||
67 | mutex_unlock(&usb_notifier_lock); | ||
68 | return ret; | ||
69 | } | ||
70 | 20 | ||
71 | /** | 21 | /** |
72 | * usb_register_notify - register a notifier callback whenever a usb change happens | 22 | * usb_register_notify - register a notifier callback whenever a usb change happens |
@@ -76,7 +26,7 @@ exit: | |||
76 | */ | 26 | */ |
77 | void usb_register_notify(struct notifier_block *nb) | 27 | void usb_register_notify(struct notifier_block *nb) |
78 | { | 28 | { |
79 | usb_notifier_chain_register(&usb_notifier_list, nb); | 29 | blocking_notifier_chain_register(&usb_notifier_list, nb); |
80 | } | 30 | } |
81 | EXPORT_SYMBOL_GPL(usb_register_notify); | 31 | EXPORT_SYMBOL_GPL(usb_register_notify); |
82 | 32 | ||
@@ -89,27 +39,28 @@ EXPORT_SYMBOL_GPL(usb_register_notify); | |||
89 | */ | 39 | */ |
90 | void usb_unregister_notify(struct notifier_block *nb) | 40 | void usb_unregister_notify(struct notifier_block *nb) |
91 | { | 41 | { |
92 | usb_notifier_chain_unregister(&usb_notifier_list, nb); | 42 | blocking_notifier_chain_unregister(&usb_notifier_list, nb); |
93 | } | 43 | } |
94 | EXPORT_SYMBOL_GPL(usb_unregister_notify); | 44 | EXPORT_SYMBOL_GPL(usb_unregister_notify); |
95 | 45 | ||
96 | 46 | ||
97 | void usb_notify_add_device(struct usb_device *udev) | 47 | void usb_notify_add_device(struct usb_device *udev) |
98 | { | 48 | { |
99 | usb_notifier_call_chain(&usb_notifier_list, USB_DEVICE_ADD, udev); | 49 | blocking_notifier_call_chain(&usb_notifier_list, USB_DEVICE_ADD, udev); |
100 | } | 50 | } |
101 | 51 | ||
102 | void usb_notify_remove_device(struct usb_device *udev) | 52 | void usb_notify_remove_device(struct usb_device *udev) |
103 | { | 53 | { |
104 | usb_notifier_call_chain(&usb_notifier_list, USB_DEVICE_REMOVE, udev); | 54 | blocking_notifier_call_chain(&usb_notifier_list, |
55 | USB_DEVICE_REMOVE, udev); | ||
105 | } | 56 | } |
106 | 57 | ||
107 | void usb_notify_add_bus(struct usb_bus *ubus) | 58 | void usb_notify_add_bus(struct usb_bus *ubus) |
108 | { | 59 | { |
109 | usb_notifier_call_chain(&usb_notifier_list, USB_BUS_ADD, ubus); | 60 | blocking_notifier_call_chain(&usb_notifier_list, USB_BUS_ADD, ubus); |
110 | } | 61 | } |
111 | 62 | ||
112 | void usb_notify_remove_bus(struct usb_bus *ubus) | 63 | void usb_notify_remove_bus(struct usb_bus *ubus) |
113 | { | 64 | { |
114 | usb_notifier_call_chain(&usb_notifier_list, USB_BUS_REMOVE, ubus); | 65 | blocking_notifier_call_chain(&usb_notifier_list, USB_BUS_REMOVE, ubus); |
115 | } | 66 | } |
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 07d882b14396..b1a8dca76430 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -55,7 +55,7 @@ | |||
55 | 55 | ||
56 | #define FBPIXMAPSIZE (1024 * 8) | 56 | #define FBPIXMAPSIZE (1024 * 8) |
57 | 57 | ||
58 | static struct notifier_block *fb_notifier_list; | 58 | static BLOCKING_NOTIFIER_HEAD(fb_notifier_list); |
59 | struct fb_info *registered_fb[FB_MAX]; | 59 | struct fb_info *registered_fb[FB_MAX]; |
60 | int num_registered_fb; | 60 | int num_registered_fb; |
61 | 61 | ||
@@ -784,7 +784,7 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) | |||
784 | 784 | ||
785 | event.info = info; | 785 | event.info = info; |
786 | event.data = &mode1; | 786 | event.data = &mode1; |
787 | ret = notifier_call_chain(&fb_notifier_list, | 787 | ret = blocking_notifier_call_chain(&fb_notifier_list, |
788 | FB_EVENT_MODE_DELETE, &event); | 788 | FB_EVENT_MODE_DELETE, &event); |
789 | } | 789 | } |
790 | 790 | ||
@@ -830,8 +830,8 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) | |||
830 | 830 | ||
831 | info->flags &= ~FBINFO_MISC_USEREVENT; | 831 | info->flags &= ~FBINFO_MISC_USEREVENT; |
832 | event.info = info; | 832 | event.info = info; |
833 | notifier_call_chain(&fb_notifier_list, evnt, | 833 | blocking_notifier_call_chain(&fb_notifier_list, |
834 | &event); | 834 | evnt, &event); |
835 | } | 835 | } |
836 | } | 836 | } |
837 | } | 837 | } |
@@ -854,7 +854,8 @@ fb_blank(struct fb_info *info, int blank) | |||
854 | 854 | ||
855 | event.info = info; | 855 | event.info = info; |
856 | event.data = ␣ | 856 | event.data = ␣ |
857 | notifier_call_chain(&fb_notifier_list, FB_EVENT_BLANK, &event); | 857 | blocking_notifier_call_chain(&fb_notifier_list, |
858 | FB_EVENT_BLANK, &event); | ||
858 | } | 859 | } |
859 | 860 | ||
860 | return ret; | 861 | return ret; |
@@ -925,7 +926,7 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
925 | con2fb.framebuffer = -1; | 926 | con2fb.framebuffer = -1; |
926 | event.info = info; | 927 | event.info = info; |
927 | event.data = &con2fb; | 928 | event.data = &con2fb; |
928 | notifier_call_chain(&fb_notifier_list, | 929 | blocking_notifier_call_chain(&fb_notifier_list, |
929 | FB_EVENT_GET_CONSOLE_MAP, &event); | 930 | FB_EVENT_GET_CONSOLE_MAP, &event); |
930 | return copy_to_user(argp, &con2fb, | 931 | return copy_to_user(argp, &con2fb, |
931 | sizeof(con2fb)) ? -EFAULT : 0; | 932 | sizeof(con2fb)) ? -EFAULT : 0; |
@@ -944,7 +945,7 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
944 | return -EINVAL; | 945 | return -EINVAL; |
945 | event.info = info; | 946 | event.info = info; |
946 | event.data = &con2fb; | 947 | event.data = &con2fb; |
947 | return notifier_call_chain(&fb_notifier_list, | 948 | return blocking_notifier_call_chain(&fb_notifier_list, |
948 | FB_EVENT_SET_CONSOLE_MAP, | 949 | FB_EVENT_SET_CONSOLE_MAP, |
949 | &event); | 950 | &event); |
950 | case FBIOBLANK: | 951 | case FBIOBLANK: |
@@ -1324,7 +1325,7 @@ register_framebuffer(struct fb_info *fb_info) | |||
1324 | devfs_mk_cdev(MKDEV(FB_MAJOR, i), | 1325 | devfs_mk_cdev(MKDEV(FB_MAJOR, i), |
1325 | S_IFCHR | S_IRUGO | S_IWUGO, "fb/%d", i); | 1326 | S_IFCHR | S_IRUGO | S_IWUGO, "fb/%d", i); |
1326 | event.info = fb_info; | 1327 | event.info = fb_info; |
1327 | notifier_call_chain(&fb_notifier_list, | 1328 | blocking_notifier_call_chain(&fb_notifier_list, |
1328 | FB_EVENT_FB_REGISTERED, &event); | 1329 | FB_EVENT_FB_REGISTERED, &event); |
1329 | return 0; | 1330 | return 0; |
1330 | } | 1331 | } |
@@ -1366,7 +1367,7 @@ unregister_framebuffer(struct fb_info *fb_info) | |||
1366 | */ | 1367 | */ |
1367 | int fb_register_client(struct notifier_block *nb) | 1368 | int fb_register_client(struct notifier_block *nb) |
1368 | { | 1369 | { |
1369 | return notifier_chain_register(&fb_notifier_list, nb); | 1370 | return blocking_notifier_chain_register(&fb_notifier_list, nb); |
1370 | } | 1371 | } |
1371 | 1372 | ||
1372 | /** | 1373 | /** |
@@ -1375,7 +1376,7 @@ int fb_register_client(struct notifier_block *nb) | |||
1375 | */ | 1376 | */ |
1376 | int fb_unregister_client(struct notifier_block *nb) | 1377 | int fb_unregister_client(struct notifier_block *nb) |
1377 | { | 1378 | { |
1378 | return notifier_chain_unregister(&fb_notifier_list, nb); | 1379 | return blocking_notifier_chain_unregister(&fb_notifier_list, nb); |
1379 | } | 1380 | } |
1380 | 1381 | ||
1381 | /** | 1382 | /** |
@@ -1393,11 +1394,13 @@ void fb_set_suspend(struct fb_info *info, int state) | |||
1393 | 1394 | ||
1394 | event.info = info; | 1395 | event.info = info; |
1395 | if (state) { | 1396 | if (state) { |
1396 | notifier_call_chain(&fb_notifier_list, FB_EVENT_SUSPEND, &event); | 1397 | blocking_notifier_call_chain(&fb_notifier_list, |
1398 | FB_EVENT_SUSPEND, &event); | ||
1397 | info->state = FBINFO_STATE_SUSPENDED; | 1399 | info->state = FBINFO_STATE_SUSPENDED; |
1398 | } else { | 1400 | } else { |
1399 | info->state = FBINFO_STATE_RUNNING; | 1401 | info->state = FBINFO_STATE_RUNNING; |
1400 | notifier_call_chain(&fb_notifier_list, FB_EVENT_RESUME, &event); | 1402 | blocking_notifier_call_chain(&fb_notifier_list, |
1403 | FB_EVENT_RESUME, &event); | ||
1401 | } | 1404 | } |
1402 | } | 1405 | } |
1403 | 1406 | ||
@@ -1469,7 +1472,7 @@ int fb_new_modelist(struct fb_info *info) | |||
1469 | 1472 | ||
1470 | if (!list_empty(&info->modelist)) { | 1473 | if (!list_empty(&info->modelist)) { |
1471 | event.info = info; | 1474 | event.info = info; |
1472 | err = notifier_call_chain(&fb_notifier_list, | 1475 | err = blocking_notifier_call_chain(&fb_notifier_list, |
1473 | FB_EVENT_NEW_MODELIST, | 1476 | FB_EVENT_NEW_MODELIST, |
1474 | &event); | 1477 | &event); |
1475 | } | 1478 | } |
@@ -1495,7 +1498,7 @@ int fb_con_duit(struct fb_info *info, int event, void *data) | |||
1495 | evnt.info = info; | 1498 | evnt.info = info; |
1496 | evnt.data = data; | 1499 | evnt.data = data; |
1497 | 1500 | ||
1498 | return notifier_call_chain(&fb_notifier_list, event, &evnt); | 1501 | return blocking_notifier_call_chain(&fb_notifier_list, event, &evnt); |
1499 | } | 1502 | } |
1500 | EXPORT_SYMBOL(fb_con_duit); | 1503 | EXPORT_SYMBOL(fb_con_duit); |
1501 | 1504 | ||
diff --git a/include/asm-i386/kdebug.h b/include/asm-i386/kdebug.h index 316138e89910..96d0828ce096 100644 --- a/include/asm-i386/kdebug.h +++ b/include/asm-i386/kdebug.h | |||
@@ -17,11 +17,9 @@ struct die_args { | |||
17 | int signr; | 17 | int signr; |
18 | }; | 18 | }; |
19 | 19 | ||
20 | /* Note - you should never unregister because that can race with NMIs. | 20 | extern int register_die_notifier(struct notifier_block *); |
21 | If you really want to do it first unregister - then synchronize_sched - then free. | 21 | extern int unregister_die_notifier(struct notifier_block *); |
22 | */ | 22 | extern struct atomic_notifier_head i386die_chain; |
23 | int register_die_notifier(struct notifier_block *nb); | ||
24 | extern struct notifier_block *i386die_chain; | ||
25 | 23 | ||
26 | 24 | ||
27 | /* Grossly misnamed. */ | 25 | /* Grossly misnamed. */ |
@@ -51,7 +49,7 @@ static inline int notify_die(enum die_val val, const char *str, | |||
51 | .trapnr = trap, | 49 | .trapnr = trap, |
52 | .signr = sig | 50 | .signr = sig |
53 | }; | 51 | }; |
54 | return notifier_call_chain(&i386die_chain, val, &args); | 52 | return atomic_notifier_call_chain(&i386die_chain, val, &args); |
55 | } | 53 | } |
56 | 54 | ||
57 | #endif | 55 | #endif |
diff --git a/include/asm-ia64/kdebug.h b/include/asm-ia64/kdebug.h index 8b01a083dde6..218c458ab60c 100644 --- a/include/asm-ia64/kdebug.h +++ b/include/asm-ia64/kdebug.h | |||
@@ -40,7 +40,7 @@ struct die_args { | |||
40 | 40 | ||
41 | extern int register_die_notifier(struct notifier_block *); | 41 | extern int register_die_notifier(struct notifier_block *); |
42 | extern int unregister_die_notifier(struct notifier_block *); | 42 | extern int unregister_die_notifier(struct notifier_block *); |
43 | extern struct notifier_block *ia64die_chain; | 43 | extern struct atomic_notifier_head ia64die_chain; |
44 | 44 | ||
45 | enum die_val { | 45 | enum die_val { |
46 | DIE_BREAK = 1, | 46 | DIE_BREAK = 1, |
@@ -81,7 +81,7 @@ static inline int notify_die(enum die_val val, char *str, struct pt_regs *regs, | |||
81 | .signr = sig | 81 | .signr = sig |
82 | }; | 82 | }; |
83 | 83 | ||
84 | return notifier_call_chain(&ia64die_chain, val, &args); | 84 | return atomic_notifier_call_chain(&ia64die_chain, val, &args); |
85 | } | 85 | } |
86 | 86 | ||
87 | #endif | 87 | #endif |
diff --git a/include/asm-powerpc/kdebug.h b/include/asm-powerpc/kdebug.h index 7c16265568e0..c01786ab5fa6 100644 --- a/include/asm-powerpc/kdebug.h +++ b/include/asm-powerpc/kdebug.h | |||
@@ -16,13 +16,9 @@ struct die_args { | |||
16 | int signr; | 16 | int signr; |
17 | }; | 17 | }; |
18 | 18 | ||
19 | /* | 19 | extern int register_die_notifier(struct notifier_block *); |
20 | Note - you should never unregister because that can race with NMIs. | 20 | extern int unregister_die_notifier(struct notifier_block *); |
21 | If you really want to do it first unregister - then synchronize_sched - | 21 | extern struct atomic_notifier_head powerpc_die_chain; |
22 | then free. | ||
23 | */ | ||
24 | int register_die_notifier(struct notifier_block *nb); | ||
25 | extern struct notifier_block *powerpc_die_chain; | ||
26 | 22 | ||
27 | /* Grossly misnamed. */ | 23 | /* Grossly misnamed. */ |
28 | enum die_val { | 24 | enum die_val { |
@@ -37,7 +33,7 @@ enum die_val { | |||
37 | static inline int notify_die(enum die_val val,char *str,struct pt_regs *regs,long err,int trap, int sig) | 33 | static inline int notify_die(enum die_val val,char *str,struct pt_regs *regs,long err,int trap, int sig) |
38 | { | 34 | { |
39 | struct die_args args = { .regs=regs, .str=str, .err=err, .trapnr=trap,.signr=sig }; | 35 | struct die_args args = { .regs=regs, .str=str, .err=err, .trapnr=trap,.signr=sig }; |
40 | return notifier_call_chain(&powerpc_die_chain, val, &args); | 36 | return atomic_notifier_call_chain(&powerpc_die_chain, val, &args); |
41 | } | 37 | } |
42 | 38 | ||
43 | #endif /* __KERNEL__ */ | 39 | #endif /* __KERNEL__ */ |
diff --git a/include/asm-sparc64/kdebug.h b/include/asm-sparc64/kdebug.h index 6321f5a0198d..4040d127ac3e 100644 --- a/include/asm-sparc64/kdebug.h +++ b/include/asm-sparc64/kdebug.h | |||
@@ -15,12 +15,9 @@ struct die_args { | |||
15 | int signr; | 15 | int signr; |
16 | }; | 16 | }; |
17 | 17 | ||
18 | /* Note - you should never unregister because that can race with NMIs. | 18 | extern int register_die_notifier(struct notifier_block *); |
19 | * If you really want to do it first unregister - then synchronize_sched | 19 | extern int unregister_die_notifier(struct notifier_block *); |
20 | * - then free. | 20 | extern struct atomic_notifier_head sparc64die_chain; |
21 | */ | ||
22 | int register_die_notifier(struct notifier_block *nb); | ||
23 | extern struct notifier_block *sparc64die_chain; | ||
24 | 21 | ||
25 | extern void bad_trap(struct pt_regs *, long); | 22 | extern void bad_trap(struct pt_regs *, long); |
26 | 23 | ||
@@ -46,7 +43,7 @@ static inline int notify_die(enum die_val val,char *str, struct pt_regs *regs, | |||
46 | .trapnr = trap, | 43 | .trapnr = trap, |
47 | .signr = sig }; | 44 | .signr = sig }; |
48 | 45 | ||
49 | return notifier_call_chain(&sparc64die_chain, val, &args); | 46 | return atomic_notifier_call_chain(&sparc64die_chain, val, &args); |
50 | } | 47 | } |
51 | 48 | ||
52 | #endif | 49 | #endif |
diff --git a/include/asm-x86_64/kdebug.h b/include/asm-x86_64/kdebug.h index b9ed4c0c8783..cf795631d9b4 100644 --- a/include/asm-x86_64/kdebug.h +++ b/include/asm-x86_64/kdebug.h | |||
@@ -5,21 +5,20 @@ | |||
5 | 5 | ||
6 | struct pt_regs; | 6 | struct pt_regs; |
7 | 7 | ||
8 | struct die_args { | 8 | struct die_args { |
9 | struct pt_regs *regs; | 9 | struct pt_regs *regs; |
10 | const char *str; | 10 | const char *str; |
11 | long err; | 11 | long err; |
12 | int trapnr; | 12 | int trapnr; |
13 | int signr; | 13 | int signr; |
14 | }; | 14 | }; |
15 | |||
16 | extern int register_die_notifier(struct notifier_block *); | ||
17 | extern int unregister_die_notifier(struct notifier_block *); | ||
18 | extern struct atomic_notifier_head die_chain; | ||
15 | 19 | ||
16 | /* Note - you should never unregister because that can race with NMIs. | ||
17 | If you really want to do it first unregister - then synchronize_sched - then free. | ||
18 | */ | ||
19 | int register_die_notifier(struct notifier_block *nb); | ||
20 | extern struct notifier_block *die_chain; | ||
21 | /* Grossly misnamed. */ | 20 | /* Grossly misnamed. */ |
22 | enum die_val { | 21 | enum die_val { |
23 | DIE_OOPS = 1, | 22 | DIE_OOPS = 1, |
24 | DIE_INT3, | 23 | DIE_INT3, |
25 | DIE_DEBUG, | 24 | DIE_DEBUG, |
@@ -33,8 +32,8 @@ enum die_val { | |||
33 | DIE_CALL, | 32 | DIE_CALL, |
34 | DIE_NMI_IPI, | 33 | DIE_NMI_IPI, |
35 | DIE_PAGE_FAULT, | 34 | DIE_PAGE_FAULT, |
36 | }; | 35 | }; |
37 | 36 | ||
38 | static inline int notify_die(enum die_val val, const char *str, | 37 | static inline int notify_die(enum die_val val, const char *str, |
39 | struct pt_regs *regs, long err, int trap, int sig) | 38 | struct pt_regs *regs, long err, int trap, int sig) |
40 | { | 39 | { |
@@ -45,7 +44,7 @@ static inline int notify_die(enum die_val val, const char *str, | |||
45 | .trapnr = trap, | 44 | .trapnr = trap, |
46 | .signr = sig | 45 | .signr = sig |
47 | }; | 46 | }; |
48 | return notifier_call_chain(&die_chain, val, &args); | 47 | return atomic_notifier_call_chain(&die_chain, val, &args); |
49 | } | 48 | } |
50 | 49 | ||
51 | extern int printk_address(unsigned long address); | 50 | extern int printk_address(unsigned long address); |
diff --git a/include/linux/adb.h b/include/linux/adb.h index e9fdc63483c7..b7305b178279 100644 --- a/include/linux/adb.h +++ b/include/linux/adb.h | |||
@@ -85,7 +85,7 @@ enum adb_message { | |||
85 | ADB_MSG_POST_RESET /* Called after resetting the bus (re-do init & register) */ | 85 | ADB_MSG_POST_RESET /* Called after resetting the bus (re-do init & register) */ |
86 | }; | 86 | }; |
87 | extern struct adb_driver *adb_controller; | 87 | extern struct adb_driver *adb_controller; |
88 | extern struct notifier_block *adb_client_list; | 88 | extern struct blocking_notifier_head adb_client_list; |
89 | 89 | ||
90 | int adb_request(struct adb_request *req, void (*done)(struct adb_request *), | 90 | int adb_request(struct adb_request *req, void (*done)(struct adb_request *), |
91 | int flags, int nbytes, ...); | 91 | int flags, int nbytes, ...); |
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 03d6cfaa5b8a..a3720f973ea5 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
@@ -87,7 +87,7 @@ extern int cond_resched(void); | |||
87 | (__x < 0) ? -__x : __x; \ | 87 | (__x < 0) ? -__x : __x; \ |
88 | }) | 88 | }) |
89 | 89 | ||
90 | extern struct notifier_block *panic_notifier_list; | 90 | extern struct atomic_notifier_head panic_notifier_list; |
91 | extern long (*panic_blink)(long time); | 91 | extern long (*panic_blink)(long time); |
92 | NORET_TYPE void panic(const char * fmt, ...) | 92 | NORET_TYPE void panic(const char * fmt, ...) |
93 | __attribute__ ((NORET_AND format (printf, 1, 2))); | 93 | __attribute__ ((NORET_AND format (printf, 1, 2))); |
diff --git a/include/linux/memory.h b/include/linux/memory.h index e251dc43d0f5..8f04143ca363 100644 --- a/include/linux/memory.h +++ b/include/linux/memory.h | |||
@@ -77,7 +77,6 @@ extern int remove_memory_block(unsigned long, struct mem_section *, int); | |||
77 | 77 | ||
78 | #define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT) | 78 | #define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT) |
79 | 79 | ||
80 | struct notifier_block; | ||
81 | 80 | ||
82 | #endif /* CONFIG_MEMORY_HOTPLUG */ | 81 | #endif /* CONFIG_MEMORY_HOTPLUG */ |
83 | 82 | ||
diff --git a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h index f32d75c4f4cf..d54d7b278e96 100644 --- a/include/linux/netfilter_ipv4/ip_conntrack.h +++ b/include/linux/netfilter_ipv4/ip_conntrack.h | |||
@@ -308,29 +308,30 @@ DECLARE_PER_CPU(struct ip_conntrack_ecache, ip_conntrack_ecache); | |||
308 | 308 | ||
309 | #define CONNTRACK_ECACHE(x) (__get_cpu_var(ip_conntrack_ecache).x) | 309 | #define CONNTRACK_ECACHE(x) (__get_cpu_var(ip_conntrack_ecache).x) |
310 | 310 | ||
311 | extern struct notifier_block *ip_conntrack_chain; | 311 | extern struct atomic_notifier_head ip_conntrack_chain; |
312 | extern struct notifier_block *ip_conntrack_expect_chain; | 312 | extern struct atomic_notifier_head ip_conntrack_expect_chain; |
313 | 313 | ||
314 | static inline int ip_conntrack_register_notifier(struct notifier_block *nb) | 314 | static inline int ip_conntrack_register_notifier(struct notifier_block *nb) |
315 | { | 315 | { |
316 | return notifier_chain_register(&ip_conntrack_chain, nb); | 316 | return atomic_notifier_chain_register(&ip_conntrack_chain, nb); |
317 | } | 317 | } |
318 | 318 | ||
319 | static inline int ip_conntrack_unregister_notifier(struct notifier_block *nb) | 319 | static inline int ip_conntrack_unregister_notifier(struct notifier_block *nb) |
320 | { | 320 | { |
321 | return notifier_chain_unregister(&ip_conntrack_chain, nb); | 321 | return atomic_notifier_chain_unregister(&ip_conntrack_chain, nb); |
322 | } | 322 | } |
323 | 323 | ||
324 | static inline int | 324 | static inline int |
325 | ip_conntrack_expect_register_notifier(struct notifier_block *nb) | 325 | ip_conntrack_expect_register_notifier(struct notifier_block *nb) |
326 | { | 326 | { |
327 | return notifier_chain_register(&ip_conntrack_expect_chain, nb); | 327 | return atomic_notifier_chain_register(&ip_conntrack_expect_chain, nb); |
328 | } | 328 | } |
329 | 329 | ||
330 | static inline int | 330 | static inline int |
331 | ip_conntrack_expect_unregister_notifier(struct notifier_block *nb) | 331 | ip_conntrack_expect_unregister_notifier(struct notifier_block *nb) |
332 | { | 332 | { |
333 | return notifier_chain_unregister(&ip_conntrack_expect_chain, nb); | 333 | return atomic_notifier_chain_unregister(&ip_conntrack_expect_chain, |
334 | nb); | ||
334 | } | 335 | } |
335 | 336 | ||
336 | extern void ip_ct_deliver_cached_events(const struct ip_conntrack *ct); | 337 | extern void ip_ct_deliver_cached_events(const struct ip_conntrack *ct); |
@@ -355,14 +356,14 @@ static inline void ip_conntrack_event(enum ip_conntrack_events event, | |||
355 | struct ip_conntrack *ct) | 356 | struct ip_conntrack *ct) |
356 | { | 357 | { |
357 | if (is_confirmed(ct) && !is_dying(ct)) | 358 | if (is_confirmed(ct) && !is_dying(ct)) |
358 | notifier_call_chain(&ip_conntrack_chain, event, ct); | 359 | atomic_notifier_call_chain(&ip_conntrack_chain, event, ct); |
359 | } | 360 | } |
360 | 361 | ||
361 | static inline void | 362 | static inline void |
362 | ip_conntrack_expect_event(enum ip_conntrack_expect_events event, | 363 | ip_conntrack_expect_event(enum ip_conntrack_expect_events event, |
363 | struct ip_conntrack_expect *exp) | 364 | struct ip_conntrack_expect *exp) |
364 | { | 365 | { |
365 | notifier_call_chain(&ip_conntrack_expect_chain, event, exp); | 366 | atomic_notifier_call_chain(&ip_conntrack_expect_chain, event, exp); |
366 | } | 367 | } |
367 | #else /* CONFIG_IP_NF_CONNTRACK_EVENTS */ | 368 | #else /* CONFIG_IP_NF_CONNTRACK_EVENTS */ |
368 | static inline void ip_conntrack_event_cache(enum ip_conntrack_events event, | 369 | static inline void ip_conntrack_event_cache(enum ip_conntrack_events event, |
diff --git a/include/linux/notifier.h b/include/linux/notifier.h index 5937dd6053c3..51dbab9710c7 100644 --- a/include/linux/notifier.h +++ b/include/linux/notifier.h | |||
@@ -10,25 +10,107 @@ | |||
10 | #ifndef _LINUX_NOTIFIER_H | 10 | #ifndef _LINUX_NOTIFIER_H |
11 | #define _LINUX_NOTIFIER_H | 11 | #define _LINUX_NOTIFIER_H |
12 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
13 | #include <linux/mutex.h> | ||
14 | #include <linux/rwsem.h> | ||
13 | 15 | ||
14 | struct notifier_block | 16 | /* |
15 | { | 17 | * Notifier chains are of three types: |
16 | int (*notifier_call)(struct notifier_block *self, unsigned long, void *); | 18 | * |
19 | * Atomic notifier chains: Chain callbacks run in interrupt/atomic | ||
20 | * context. Callouts are not allowed to block. | ||
21 | * Blocking notifier chains: Chain callbacks run in process context. | ||
22 | * Callouts are allowed to block. | ||
23 | * Raw notifier chains: There are no restrictions on callbacks, | ||
24 | * registration, or unregistration. All locking and protection | ||
25 | * must be provided by the caller. | ||
26 | * | ||
27 | * atomic_notifier_chain_register() may be called from an atomic context, | ||
28 | * but blocking_notifier_chain_register() must be called from a process | ||
29 | * context. Ditto for the corresponding _unregister() routines. | ||
30 | * | ||
31 | * atomic_notifier_chain_unregister() and blocking_notifier_chain_unregister() | ||
32 | * _must not_ be called from within the call chain. | ||
33 | */ | ||
34 | |||
35 | struct notifier_block { | ||
36 | int (*notifier_call)(struct notifier_block *, unsigned long, void *); | ||
17 | struct notifier_block *next; | 37 | struct notifier_block *next; |
18 | int priority; | 38 | int priority; |
19 | }; | 39 | }; |
20 | 40 | ||
41 | struct atomic_notifier_head { | ||
42 | spinlock_t lock; | ||
43 | struct notifier_block *head; | ||
44 | }; | ||
45 | |||
46 | struct blocking_notifier_head { | ||
47 | struct rw_semaphore rwsem; | ||
48 | struct notifier_block *head; | ||
49 | }; | ||
50 | |||
51 | struct raw_notifier_head { | ||
52 | struct notifier_block *head; | ||
53 | }; | ||
54 | |||
55 | #define ATOMIC_INIT_NOTIFIER_HEAD(name) do { \ | ||
56 | spin_lock_init(&(name)->lock); \ | ||
57 | (name)->head = NULL; \ | ||
58 | } while (0) | ||
59 | #define BLOCKING_INIT_NOTIFIER_HEAD(name) do { \ | ||
60 | init_rwsem(&(name)->rwsem); \ | ||
61 | (name)->head = NULL; \ | ||
62 | } while (0) | ||
63 | #define RAW_INIT_NOTIFIER_HEAD(name) do { \ | ||
64 | (name)->head = NULL; \ | ||
65 | } while (0) | ||
66 | |||
67 | #define ATOMIC_NOTIFIER_INIT(name) { \ | ||
68 | .lock = SPIN_LOCK_UNLOCKED, \ | ||
69 | .head = NULL } | ||
70 | #define BLOCKING_NOTIFIER_INIT(name) { \ | ||
71 | .rwsem = __RWSEM_INITIALIZER((name).rwsem), \ | ||
72 | .head = NULL } | ||
73 | #define RAW_NOTIFIER_INIT(name) { \ | ||
74 | .head = NULL } | ||
75 | |||
76 | #define ATOMIC_NOTIFIER_HEAD(name) \ | ||
77 | struct atomic_notifier_head name = \ | ||
78 | ATOMIC_NOTIFIER_INIT(name) | ||
79 | #define BLOCKING_NOTIFIER_HEAD(name) \ | ||
80 | struct blocking_notifier_head name = \ | ||
81 | BLOCKING_NOTIFIER_INIT(name) | ||
82 | #define RAW_NOTIFIER_HEAD(name) \ | ||
83 | struct raw_notifier_head name = \ | ||
84 | RAW_NOTIFIER_INIT(name) | ||
21 | 85 | ||
22 | #ifdef __KERNEL__ | 86 | #ifdef __KERNEL__ |
23 | 87 | ||
24 | extern int notifier_chain_register(struct notifier_block **list, struct notifier_block *n); | 88 | extern int atomic_notifier_chain_register(struct atomic_notifier_head *, |
25 | extern int notifier_chain_unregister(struct notifier_block **nl, struct notifier_block *n); | 89 | struct notifier_block *); |
26 | extern int notifier_call_chain(struct notifier_block **n, unsigned long val, void *v); | 90 | extern int blocking_notifier_chain_register(struct blocking_notifier_head *, |
91 | struct notifier_block *); | ||
92 | extern int raw_notifier_chain_register(struct raw_notifier_head *, | ||
93 | struct notifier_block *); | ||
94 | |||
95 | extern int atomic_notifier_chain_unregister(struct atomic_notifier_head *, | ||
96 | struct notifier_block *); | ||
97 | extern int blocking_notifier_chain_unregister(struct blocking_notifier_head *, | ||
98 | struct notifier_block *); | ||
99 | extern int raw_notifier_chain_unregister(struct raw_notifier_head *, | ||
100 | struct notifier_block *); | ||
101 | |||
102 | extern int atomic_notifier_call_chain(struct atomic_notifier_head *, | ||
103 | unsigned long val, void *v); | ||
104 | extern int blocking_notifier_call_chain(struct blocking_notifier_head *, | ||
105 | unsigned long val, void *v); | ||
106 | extern int raw_notifier_call_chain(struct raw_notifier_head *, | ||
107 | unsigned long val, void *v); | ||
27 | 108 | ||
28 | #define NOTIFY_DONE 0x0000 /* Don't care */ | 109 | #define NOTIFY_DONE 0x0000 /* Don't care */ |
29 | #define NOTIFY_OK 0x0001 /* Suits me */ | 110 | #define NOTIFY_OK 0x0001 /* Suits me */ |
30 | #define NOTIFY_STOP_MASK 0x8000 /* Don't call further */ | 111 | #define NOTIFY_STOP_MASK 0x8000 /* Don't call further */ |
31 | #define NOTIFY_BAD (NOTIFY_STOP_MASK|0x0002) /* Bad/Veto action */ | 112 | #define NOTIFY_BAD (NOTIFY_STOP_MASK|0x0002) |
113 | /* Bad/Veto action */ | ||
32 | /* | 114 | /* |
33 | * Clean way to return from the notifier and stop further calls. | 115 | * Clean way to return from the notifier and stop further calls. |
34 | */ | 116 | */ |
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h index b6f0905a4ee2..916013ca4a5c 100644 --- a/include/net/netfilter/nf_conntrack.h +++ b/include/net/netfilter/nf_conntrack.h | |||
@@ -300,29 +300,30 @@ DECLARE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache); | |||
300 | 300 | ||
301 | #define CONNTRACK_ECACHE(x) (__get_cpu_var(nf_conntrack_ecache).x) | 301 | #define CONNTRACK_ECACHE(x) (__get_cpu_var(nf_conntrack_ecache).x) |
302 | 302 | ||
303 | extern struct notifier_block *nf_conntrack_chain; | 303 | extern struct atomic_notifier_head nf_conntrack_chain; |
304 | extern struct notifier_block *nf_conntrack_expect_chain; | 304 | extern struct atomic_notifier_head nf_conntrack_expect_chain; |
305 | 305 | ||
306 | static inline int nf_conntrack_register_notifier(struct notifier_block *nb) | 306 | static inline int nf_conntrack_register_notifier(struct notifier_block *nb) |
307 | { | 307 | { |
308 | return notifier_chain_register(&nf_conntrack_chain, nb); | 308 | return atomic_notifier_chain_register(&nf_conntrack_chain, nb); |
309 | } | 309 | } |
310 | 310 | ||
311 | static inline int nf_conntrack_unregister_notifier(struct notifier_block *nb) | 311 | static inline int nf_conntrack_unregister_notifier(struct notifier_block *nb) |
312 | { | 312 | { |
313 | return notifier_chain_unregister(&nf_conntrack_chain, nb); | 313 | return atomic_notifier_chain_unregister(&nf_conntrack_chain, nb); |
314 | } | 314 | } |
315 | 315 | ||
316 | static inline int | 316 | static inline int |
317 | nf_conntrack_expect_register_notifier(struct notifier_block *nb) | 317 | nf_conntrack_expect_register_notifier(struct notifier_block *nb) |
318 | { | 318 | { |
319 | return notifier_chain_register(&nf_conntrack_expect_chain, nb); | 319 | return atomic_notifier_chain_register(&nf_conntrack_expect_chain, nb); |
320 | } | 320 | } |
321 | 321 | ||
322 | static inline int | 322 | static inline int |
323 | nf_conntrack_expect_unregister_notifier(struct notifier_block *nb) | 323 | nf_conntrack_expect_unregister_notifier(struct notifier_block *nb) |
324 | { | 324 | { |
325 | return notifier_chain_unregister(&nf_conntrack_expect_chain, nb); | 325 | return atomic_notifier_chain_unregister(&nf_conntrack_expect_chain, |
326 | nb); | ||
326 | } | 327 | } |
327 | 328 | ||
328 | extern void nf_ct_deliver_cached_events(const struct nf_conn *ct); | 329 | extern void nf_ct_deliver_cached_events(const struct nf_conn *ct); |
@@ -347,14 +348,14 @@ static inline void nf_conntrack_event(enum ip_conntrack_events event, | |||
347 | struct nf_conn *ct) | 348 | struct nf_conn *ct) |
348 | { | 349 | { |
349 | if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) | 350 | if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) |
350 | notifier_call_chain(&nf_conntrack_chain, event, ct); | 351 | atomic_notifier_call_chain(&nf_conntrack_chain, event, ct); |
351 | } | 352 | } |
352 | 353 | ||
353 | static inline void | 354 | static inline void |
354 | nf_conntrack_expect_event(enum ip_conntrack_expect_events event, | 355 | nf_conntrack_expect_event(enum ip_conntrack_expect_events event, |
355 | struct nf_conntrack_expect *exp) | 356 | struct nf_conntrack_expect *exp) |
356 | { | 357 | { |
357 | notifier_call_chain(&nf_conntrack_expect_chain, event, exp); | 358 | atomic_notifier_call_chain(&nf_conntrack_expect_chain, event, exp); |
358 | } | 359 | } |
359 | #else /* CONFIG_NF_CONNTRACK_EVENTS */ | 360 | #else /* CONFIG_NF_CONNTRACK_EVENTS */ |
360 | static inline void nf_conntrack_event_cache(enum ip_conntrack_events event, | 361 | static inline void nf_conntrack_event_cache(enum ip_conntrack_events event, |
diff --git a/kernel/cpu.c b/kernel/cpu.c index 8be22bd80933..fe2b8d0bfe4c 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
@@ -18,7 +18,7 @@ | |||
18 | /* This protects CPUs going up and down... */ | 18 | /* This protects CPUs going up and down... */ |
19 | static DECLARE_MUTEX(cpucontrol); | 19 | static DECLARE_MUTEX(cpucontrol); |
20 | 20 | ||
21 | static struct notifier_block *cpu_chain; | 21 | static BLOCKING_NOTIFIER_HEAD(cpu_chain); |
22 | 22 | ||
23 | #ifdef CONFIG_HOTPLUG_CPU | 23 | #ifdef CONFIG_HOTPLUG_CPU |
24 | static struct task_struct *lock_cpu_hotplug_owner; | 24 | static struct task_struct *lock_cpu_hotplug_owner; |
@@ -71,21 +71,13 @@ EXPORT_SYMBOL_GPL(lock_cpu_hotplug_interruptible); | |||
71 | /* Need to know about CPUs going up/down? */ | 71 | /* Need to know about CPUs going up/down? */ |
72 | int register_cpu_notifier(struct notifier_block *nb) | 72 | int register_cpu_notifier(struct notifier_block *nb) |
73 | { | 73 | { |
74 | int ret; | 74 | return blocking_notifier_chain_register(&cpu_chain, nb); |
75 | |||
76 | if ((ret = lock_cpu_hotplug_interruptible()) != 0) | ||
77 | return ret; | ||
78 | ret = notifier_chain_register(&cpu_chain, nb); | ||
79 | unlock_cpu_hotplug(); | ||
80 | return ret; | ||
81 | } | 75 | } |
82 | EXPORT_SYMBOL(register_cpu_notifier); | 76 | EXPORT_SYMBOL(register_cpu_notifier); |
83 | 77 | ||
84 | void unregister_cpu_notifier(struct notifier_block *nb) | 78 | void unregister_cpu_notifier(struct notifier_block *nb) |
85 | { | 79 | { |
86 | lock_cpu_hotplug(); | 80 | blocking_notifier_chain_unregister(&cpu_chain, nb); |
87 | notifier_chain_unregister(&cpu_chain, nb); | ||
88 | unlock_cpu_hotplug(); | ||
89 | } | 81 | } |
90 | EXPORT_SYMBOL(unregister_cpu_notifier); | 82 | EXPORT_SYMBOL(unregister_cpu_notifier); |
91 | 83 | ||
@@ -141,7 +133,7 @@ int cpu_down(unsigned int cpu) | |||
141 | goto out; | 133 | goto out; |
142 | } | 134 | } |
143 | 135 | ||
144 | err = notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE, | 136 | err = blocking_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE, |
145 | (void *)(long)cpu); | 137 | (void *)(long)cpu); |
146 | if (err == NOTIFY_BAD) { | 138 | if (err == NOTIFY_BAD) { |
147 | printk("%s: attempt to take down CPU %u failed\n", | 139 | printk("%s: attempt to take down CPU %u failed\n", |
@@ -159,7 +151,7 @@ int cpu_down(unsigned int cpu) | |||
159 | p = __stop_machine_run(take_cpu_down, NULL, cpu); | 151 | p = __stop_machine_run(take_cpu_down, NULL, cpu); |
160 | if (IS_ERR(p)) { | 152 | if (IS_ERR(p)) { |
161 | /* CPU didn't die: tell everyone. Can't complain. */ | 153 | /* CPU didn't die: tell everyone. Can't complain. */ |
162 | if (notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED, | 154 | if (blocking_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED, |
163 | (void *)(long)cpu) == NOTIFY_BAD) | 155 | (void *)(long)cpu) == NOTIFY_BAD) |
164 | BUG(); | 156 | BUG(); |
165 | 157 | ||
@@ -182,8 +174,8 @@ int cpu_down(unsigned int cpu) | |||
182 | put_cpu(); | 174 | put_cpu(); |
183 | 175 | ||
184 | /* CPU is completely dead: tell everyone. Too late to complain. */ | 176 | /* CPU is completely dead: tell everyone. Too late to complain. */ |
185 | if (notifier_call_chain(&cpu_chain, CPU_DEAD, (void *)(long)cpu) | 177 | if (blocking_notifier_call_chain(&cpu_chain, CPU_DEAD, |
186 | == NOTIFY_BAD) | 178 | (void *)(long)cpu) == NOTIFY_BAD) |
187 | BUG(); | 179 | BUG(); |
188 | 180 | ||
189 | check_for_tasks(cpu); | 181 | check_for_tasks(cpu); |
@@ -211,7 +203,7 @@ int __devinit cpu_up(unsigned int cpu) | |||
211 | goto out; | 203 | goto out; |
212 | } | 204 | } |
213 | 205 | ||
214 | ret = notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu); | 206 | ret = blocking_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu); |
215 | if (ret == NOTIFY_BAD) { | 207 | if (ret == NOTIFY_BAD) { |
216 | printk("%s: attempt to bring up CPU %u failed\n", | 208 | printk("%s: attempt to bring up CPU %u failed\n", |
217 | __FUNCTION__, cpu); | 209 | __FUNCTION__, cpu); |
@@ -226,11 +218,12 @@ int __devinit cpu_up(unsigned int cpu) | |||
226 | BUG_ON(!cpu_online(cpu)); | 218 | BUG_ON(!cpu_online(cpu)); |
227 | 219 | ||
228 | /* Now call notifier in preparation. */ | 220 | /* Now call notifier in preparation. */ |
229 | notifier_call_chain(&cpu_chain, CPU_ONLINE, hcpu); | 221 | blocking_notifier_call_chain(&cpu_chain, CPU_ONLINE, hcpu); |
230 | 222 | ||
231 | out_notify: | 223 | out_notify: |
232 | if (ret != 0) | 224 | if (ret != 0) |
233 | notifier_call_chain(&cpu_chain, CPU_UP_CANCELED, hcpu); | 225 | blocking_notifier_call_chain(&cpu_chain, |
226 | CPU_UP_CANCELED, hcpu); | ||
234 | out: | 227 | out: |
235 | unlock_cpu_hotplug(); | 228 | unlock_cpu_hotplug(); |
236 | return ret; | 229 | return ret; |
diff --git a/kernel/module.c b/kernel/module.c index ddfe45ac2fd1..4fafd58038a0 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -64,26 +64,17 @@ static DEFINE_SPINLOCK(modlist_lock); | |||
64 | static DEFINE_MUTEX(module_mutex); | 64 | static DEFINE_MUTEX(module_mutex); |
65 | static LIST_HEAD(modules); | 65 | static LIST_HEAD(modules); |
66 | 66 | ||
67 | static DEFINE_MUTEX(notify_mutex); | 67 | static BLOCKING_NOTIFIER_HEAD(module_notify_list); |
68 | static struct notifier_block * module_notify_list; | ||
69 | 68 | ||
70 | int register_module_notifier(struct notifier_block * nb) | 69 | int register_module_notifier(struct notifier_block * nb) |
71 | { | 70 | { |
72 | int err; | 71 | return blocking_notifier_chain_register(&module_notify_list, nb); |
73 | mutex_lock(¬ify_mutex); | ||
74 | err = notifier_chain_register(&module_notify_list, nb); | ||
75 | mutex_unlock(¬ify_mutex); | ||
76 | return err; | ||
77 | } | 72 | } |
78 | EXPORT_SYMBOL(register_module_notifier); | 73 | EXPORT_SYMBOL(register_module_notifier); |
79 | 74 | ||
80 | int unregister_module_notifier(struct notifier_block * nb) | 75 | int unregister_module_notifier(struct notifier_block * nb) |
81 | { | 76 | { |
82 | int err; | 77 | return blocking_notifier_chain_unregister(&module_notify_list, nb); |
83 | mutex_lock(¬ify_mutex); | ||
84 | err = notifier_chain_unregister(&module_notify_list, nb); | ||
85 | mutex_unlock(¬ify_mutex); | ||
86 | return err; | ||
87 | } | 78 | } |
88 | EXPORT_SYMBOL(unregister_module_notifier); | 79 | EXPORT_SYMBOL(unregister_module_notifier); |
89 | 80 | ||
@@ -1816,9 +1807,8 @@ sys_init_module(void __user *umod, | |||
1816 | /* Drop lock so they can recurse */ | 1807 | /* Drop lock so they can recurse */ |
1817 | mutex_unlock(&module_mutex); | 1808 | mutex_unlock(&module_mutex); |
1818 | 1809 | ||
1819 | mutex_lock(¬ify_mutex); | 1810 | blocking_notifier_call_chain(&module_notify_list, |
1820 | notifier_call_chain(&module_notify_list, MODULE_STATE_COMING, mod); | 1811 | MODULE_STATE_COMING, mod); |
1821 | mutex_unlock(¬ify_mutex); | ||
1822 | 1812 | ||
1823 | /* Start the module */ | 1813 | /* Start the module */ |
1824 | if (mod->init != NULL) | 1814 | if (mod->init != NULL) |
diff --git a/kernel/panic.c b/kernel/panic.c index acd95adddb93..f895c7c01d5b 100644 --- a/kernel/panic.c +++ b/kernel/panic.c | |||
@@ -29,7 +29,7 @@ static DEFINE_SPINLOCK(pause_on_oops_lock); | |||
29 | int panic_timeout; | 29 | int panic_timeout; |
30 | EXPORT_SYMBOL(panic_timeout); | 30 | EXPORT_SYMBOL(panic_timeout); |
31 | 31 | ||
32 | struct notifier_block *panic_notifier_list; | 32 | ATOMIC_NOTIFIER_HEAD(panic_notifier_list); |
33 | 33 | ||
34 | EXPORT_SYMBOL(panic_notifier_list); | 34 | EXPORT_SYMBOL(panic_notifier_list); |
35 | 35 | ||
@@ -97,7 +97,7 @@ NORET_TYPE void panic(const char * fmt, ...) | |||
97 | smp_send_stop(); | 97 | smp_send_stop(); |
98 | #endif | 98 | #endif |
99 | 99 | ||
100 | notifier_call_chain(&panic_notifier_list, 0, buf); | 100 | atomic_notifier_call_chain(&panic_notifier_list, 0, buf); |
101 | 101 | ||
102 | if (!panic_blink) | 102 | if (!panic_blink) |
103 | panic_blink = no_blink; | 103 | panic_blink = no_blink; |
diff --git a/kernel/profile.c b/kernel/profile.c index ad81f799a9b4..5a730fdb1a2c 100644 --- a/kernel/profile.c +++ b/kernel/profile.c | |||
@@ -87,72 +87,52 @@ void __init profile_init(void) | |||
87 | 87 | ||
88 | #ifdef CONFIG_PROFILING | 88 | #ifdef CONFIG_PROFILING |
89 | 89 | ||
90 | static DECLARE_RWSEM(profile_rwsem); | 90 | static BLOCKING_NOTIFIER_HEAD(task_exit_notifier); |
91 | static DEFINE_RWLOCK(handoff_lock); | 91 | static ATOMIC_NOTIFIER_HEAD(task_free_notifier); |
92 | static struct notifier_block * task_exit_notifier; | 92 | static BLOCKING_NOTIFIER_HEAD(munmap_notifier); |
93 | static struct notifier_block * task_free_notifier; | ||
94 | static struct notifier_block * munmap_notifier; | ||
95 | 93 | ||
96 | void profile_task_exit(struct task_struct * task) | 94 | void profile_task_exit(struct task_struct * task) |
97 | { | 95 | { |
98 | down_read(&profile_rwsem); | 96 | blocking_notifier_call_chain(&task_exit_notifier, 0, task); |
99 | notifier_call_chain(&task_exit_notifier, 0, task); | ||
100 | up_read(&profile_rwsem); | ||
101 | } | 97 | } |
102 | 98 | ||
103 | int profile_handoff_task(struct task_struct * task) | 99 | int profile_handoff_task(struct task_struct * task) |
104 | { | 100 | { |
105 | int ret; | 101 | int ret; |
106 | read_lock(&handoff_lock); | 102 | ret = atomic_notifier_call_chain(&task_free_notifier, 0, task); |
107 | ret = notifier_call_chain(&task_free_notifier, 0, task); | ||
108 | read_unlock(&handoff_lock); | ||
109 | return (ret == NOTIFY_OK) ? 1 : 0; | 103 | return (ret == NOTIFY_OK) ? 1 : 0; |
110 | } | 104 | } |
111 | 105 | ||
112 | void profile_munmap(unsigned long addr) | 106 | void profile_munmap(unsigned long addr) |
113 | { | 107 | { |
114 | down_read(&profile_rwsem); | 108 | blocking_notifier_call_chain(&munmap_notifier, 0, (void *)addr); |
115 | notifier_call_chain(&munmap_notifier, 0, (void *)addr); | ||
116 | up_read(&profile_rwsem); | ||
117 | } | 109 | } |
118 | 110 | ||
119 | int task_handoff_register(struct notifier_block * n) | 111 | int task_handoff_register(struct notifier_block * n) |
120 | { | 112 | { |
121 | int err = -EINVAL; | 113 | return atomic_notifier_chain_register(&task_free_notifier, n); |
122 | |||
123 | write_lock(&handoff_lock); | ||
124 | err = notifier_chain_register(&task_free_notifier, n); | ||
125 | write_unlock(&handoff_lock); | ||
126 | return err; | ||
127 | } | 114 | } |
128 | 115 | ||
129 | int task_handoff_unregister(struct notifier_block * n) | 116 | int task_handoff_unregister(struct notifier_block * n) |
130 | { | 117 | { |
131 | int err = -EINVAL; | 118 | return atomic_notifier_chain_unregister(&task_free_notifier, n); |
132 | |||
133 | write_lock(&handoff_lock); | ||
134 | err = notifier_chain_unregister(&task_free_notifier, n); | ||
135 | write_unlock(&handoff_lock); | ||
136 | return err; | ||
137 | } | 119 | } |
138 | 120 | ||
139 | int profile_event_register(enum profile_type type, struct notifier_block * n) | 121 | int profile_event_register(enum profile_type type, struct notifier_block * n) |
140 | { | 122 | { |
141 | int err = -EINVAL; | 123 | int err = -EINVAL; |
142 | 124 | ||
143 | down_write(&profile_rwsem); | ||
144 | |||
145 | switch (type) { | 125 | switch (type) { |
146 | case PROFILE_TASK_EXIT: | 126 | case PROFILE_TASK_EXIT: |
147 | err = notifier_chain_register(&task_exit_notifier, n); | 127 | err = blocking_notifier_chain_register( |
128 | &task_exit_notifier, n); | ||
148 | break; | 129 | break; |
149 | case PROFILE_MUNMAP: | 130 | case PROFILE_MUNMAP: |
150 | err = notifier_chain_register(&munmap_notifier, n); | 131 | err = blocking_notifier_chain_register( |
132 | &munmap_notifier, n); | ||
151 | break; | 133 | break; |
152 | } | 134 | } |
153 | 135 | ||
154 | up_write(&profile_rwsem); | ||
155 | |||
156 | return err; | 136 | return err; |
157 | } | 137 | } |
158 | 138 | ||
@@ -161,18 +141,17 @@ int profile_event_unregister(enum profile_type type, struct notifier_block * n) | |||
161 | { | 141 | { |
162 | int err = -EINVAL; | 142 | int err = -EINVAL; |
163 | 143 | ||
164 | down_write(&profile_rwsem); | ||
165 | |||
166 | switch (type) { | 144 | switch (type) { |
167 | case PROFILE_TASK_EXIT: | 145 | case PROFILE_TASK_EXIT: |
168 | err = notifier_chain_unregister(&task_exit_notifier, n); | 146 | err = blocking_notifier_chain_unregister( |
147 | &task_exit_notifier, n); | ||
169 | break; | 148 | break; |
170 | case PROFILE_MUNMAP: | 149 | case PROFILE_MUNMAP: |
171 | err = notifier_chain_unregister(&munmap_notifier, n); | 150 | err = blocking_notifier_chain_unregister( |
151 | &munmap_notifier, n); | ||
172 | break; | 152 | break; |
173 | } | 153 | } |
174 | 154 | ||
175 | up_write(&profile_rwsem); | ||
176 | return err; | 155 | return err; |
177 | } | 156 | } |
178 | 157 | ||
diff --git a/kernel/softlockup.c b/kernel/softlockup.c index d9b3d5847ed8..ced91e1ff564 100644 --- a/kernel/softlockup.c +++ b/kernel/softlockup.c | |||
@@ -152,5 +152,5 @@ __init void spawn_softlockup_task(void) | |||
152 | cpu_callback(&cpu_nfb, CPU_ONLINE, cpu); | 152 | cpu_callback(&cpu_nfb, CPU_ONLINE, cpu); |
153 | register_cpu_notifier(&cpu_nfb); | 153 | register_cpu_notifier(&cpu_nfb); |
154 | 154 | ||
155 | notifier_chain_register(&panic_notifier_list, &panic_block); | 155 | atomic_notifier_chain_register(&panic_notifier_list, &panic_block); |
156 | } | 156 | } |
diff --git a/kernel/sys.c b/kernel/sys.c index 38bc73ede2ba..c93d37f71aef 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -95,99 +95,304 @@ int cad_pid = 1; | |||
95 | * and the like. | 95 | * and the like. |
96 | */ | 96 | */ |
97 | 97 | ||
98 | static struct notifier_block *reboot_notifier_list; | 98 | static BLOCKING_NOTIFIER_HEAD(reboot_notifier_list); |
99 | static DEFINE_RWLOCK(notifier_lock); | 99 | |
100 | /* | ||
101 | * Notifier chain core routines. The exported routines below | ||
102 | * are layered on top of these, with appropriate locking added. | ||
103 | */ | ||
104 | |||
105 | static int notifier_chain_register(struct notifier_block **nl, | ||
106 | struct notifier_block *n) | ||
107 | { | ||
108 | while ((*nl) != NULL) { | ||
109 | if (n->priority > (*nl)->priority) | ||
110 | break; | ||
111 | nl = &((*nl)->next); | ||
112 | } | ||
113 | n->next = *nl; | ||
114 | rcu_assign_pointer(*nl, n); | ||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | static int notifier_chain_unregister(struct notifier_block **nl, | ||
119 | struct notifier_block *n) | ||
120 | { | ||
121 | while ((*nl) != NULL) { | ||
122 | if ((*nl) == n) { | ||
123 | rcu_assign_pointer(*nl, n->next); | ||
124 | return 0; | ||
125 | } | ||
126 | nl = &((*nl)->next); | ||
127 | } | ||
128 | return -ENOENT; | ||
129 | } | ||
130 | |||
131 | static int __kprobes notifier_call_chain(struct notifier_block **nl, | ||
132 | unsigned long val, void *v) | ||
133 | { | ||
134 | int ret = NOTIFY_DONE; | ||
135 | struct notifier_block *nb; | ||
136 | |||
137 | nb = rcu_dereference(*nl); | ||
138 | while (nb) { | ||
139 | ret = nb->notifier_call(nb, val, v); | ||
140 | if ((ret & NOTIFY_STOP_MASK) == NOTIFY_STOP_MASK) | ||
141 | break; | ||
142 | nb = rcu_dereference(nb->next); | ||
143 | } | ||
144 | return ret; | ||
145 | } | ||
146 | |||
147 | /* | ||
148 | * Atomic notifier chain routines. Registration and unregistration | ||
149 | * use a mutex, and call_chain is synchronized by RCU (no locks). | ||
150 | */ | ||
100 | 151 | ||
101 | /** | 152 | /** |
102 | * notifier_chain_register - Add notifier to a notifier chain | 153 | * atomic_notifier_chain_register - Add notifier to an atomic notifier chain |
103 | * @list: Pointer to root list pointer | 154 | * @nh: Pointer to head of the atomic notifier chain |
104 | * @n: New entry in notifier chain | 155 | * @n: New entry in notifier chain |
105 | * | 156 | * |
106 | * Adds a notifier to a notifier chain. | 157 | * Adds a notifier to an atomic notifier chain. |
107 | * | 158 | * |
108 | * Currently always returns zero. | 159 | * Currently always returns zero. |
109 | */ | 160 | */ |
161 | |||
162 | int atomic_notifier_chain_register(struct atomic_notifier_head *nh, | ||
163 | struct notifier_block *n) | ||
164 | { | ||
165 | unsigned long flags; | ||
166 | int ret; | ||
167 | |||
168 | spin_lock_irqsave(&nh->lock, flags); | ||
169 | ret = notifier_chain_register(&nh->head, n); | ||
170 | spin_unlock_irqrestore(&nh->lock, flags); | ||
171 | return ret; | ||
172 | } | ||
173 | |||
174 | EXPORT_SYMBOL_GPL(atomic_notifier_chain_register); | ||
175 | |||
176 | /** | ||
177 | * atomic_notifier_chain_unregister - Remove notifier from an atomic notifier chain | ||
178 | * @nh: Pointer to head of the atomic notifier chain | ||
179 | * @n: Entry to remove from notifier chain | ||
180 | * | ||
181 | * Removes a notifier from an atomic notifier chain. | ||
182 | * | ||
183 | * Returns zero on success or %-ENOENT on failure. | ||
184 | */ | ||
185 | int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh, | ||
186 | struct notifier_block *n) | ||
187 | { | ||
188 | unsigned long flags; | ||
189 | int ret; | ||
190 | |||
191 | spin_lock_irqsave(&nh->lock, flags); | ||
192 | ret = notifier_chain_unregister(&nh->head, n); | ||
193 | spin_unlock_irqrestore(&nh->lock, flags); | ||
194 | synchronize_rcu(); | ||
195 | return ret; | ||
196 | } | ||
197 | |||
198 | EXPORT_SYMBOL_GPL(atomic_notifier_chain_unregister); | ||
199 | |||
200 | /** | ||
201 | * atomic_notifier_call_chain - Call functions in an atomic notifier chain | ||
202 | * @nh: Pointer to head of the atomic notifier chain | ||
203 | * @val: Value passed unmodified to notifier function | ||
204 | * @v: Pointer passed unmodified to notifier function | ||
205 | * | ||
206 | * Calls each function in a notifier chain in turn. The functions | ||
207 | * run in an atomic context, so they must not block. | ||
208 | * This routine uses RCU to synchronize with changes to the chain. | ||
209 | * | ||
210 | * If the return value of the notifier can be and'ed | ||
211 | * with %NOTIFY_STOP_MASK then atomic_notifier_call_chain | ||
212 | * will return immediately, with the return value of | ||
213 | * the notifier function which halted execution. | ||
214 | * Otherwise the return value is the return value | ||
215 | * of the last notifier function called. | ||
216 | */ | ||
110 | 217 | ||
111 | int notifier_chain_register(struct notifier_block **list, struct notifier_block *n) | 218 | int atomic_notifier_call_chain(struct atomic_notifier_head *nh, |
219 | unsigned long val, void *v) | ||
112 | { | 220 | { |
113 | write_lock(¬ifier_lock); | 221 | int ret; |
114 | while(*list) | 222 | |
115 | { | 223 | rcu_read_lock(); |
116 | if(n->priority > (*list)->priority) | 224 | ret = notifier_call_chain(&nh->head, val, v); |
117 | break; | 225 | rcu_read_unlock(); |
118 | list= &((*list)->next); | 226 | return ret; |
119 | } | ||
120 | n->next = *list; | ||
121 | *list=n; | ||
122 | write_unlock(¬ifier_lock); | ||
123 | return 0; | ||
124 | } | 227 | } |
125 | 228 | ||
126 | EXPORT_SYMBOL(notifier_chain_register); | 229 | EXPORT_SYMBOL_GPL(atomic_notifier_call_chain); |
230 | |||
231 | /* | ||
232 | * Blocking notifier chain routines. All access to the chain is | ||
233 | * synchronized by an rwsem. | ||
234 | */ | ||
127 | 235 | ||
128 | /** | 236 | /** |
129 | * notifier_chain_unregister - Remove notifier from a notifier chain | 237 | * blocking_notifier_chain_register - Add notifier to a blocking notifier chain |
130 | * @nl: Pointer to root list pointer | 238 | * @nh: Pointer to head of the blocking notifier chain |
131 | * @n: New entry in notifier chain | 239 | * @n: New entry in notifier chain |
132 | * | 240 | * |
133 | * Removes a notifier from a notifier chain. | 241 | * Adds a notifier to a blocking notifier chain. |
242 | * Must be called in process context. | ||
134 | * | 243 | * |
135 | * Returns zero on success, or %-ENOENT on failure. | 244 | * Currently always returns zero. |
136 | */ | 245 | */ |
137 | 246 | ||
138 | int notifier_chain_unregister(struct notifier_block **nl, struct notifier_block *n) | 247 | int blocking_notifier_chain_register(struct blocking_notifier_head *nh, |
248 | struct notifier_block *n) | ||
139 | { | 249 | { |
140 | write_lock(¬ifier_lock); | 250 | int ret; |
141 | while((*nl)!=NULL) | 251 | |
142 | { | 252 | /* |
143 | if((*nl)==n) | 253 | * This code gets used during boot-up, when task switching is |
144 | { | 254 | * not yet working and interrupts must remain disabled. At |
145 | *nl=n->next; | 255 | * such times we must not call down_write(). |
146 | write_unlock(¬ifier_lock); | 256 | */ |
147 | return 0; | 257 | if (unlikely(system_state == SYSTEM_BOOTING)) |
148 | } | 258 | return notifier_chain_register(&nh->head, n); |
149 | nl=&((*nl)->next); | 259 | |
150 | } | 260 | down_write(&nh->rwsem); |
151 | write_unlock(¬ifier_lock); | 261 | ret = notifier_chain_register(&nh->head, n); |
152 | return -ENOENT; | 262 | up_write(&nh->rwsem); |
263 | return ret; | ||
153 | } | 264 | } |
154 | 265 | ||
155 | EXPORT_SYMBOL(notifier_chain_unregister); | 266 | EXPORT_SYMBOL_GPL(blocking_notifier_chain_register); |
156 | 267 | ||
157 | /** | 268 | /** |
158 | * notifier_call_chain - Call functions in a notifier chain | 269 | * blocking_notifier_chain_unregister - Remove notifier from a blocking notifier chain |
159 | * @n: Pointer to root pointer of notifier chain | 270 | * @nh: Pointer to head of the blocking notifier chain |
271 | * @n: Entry to remove from notifier chain | ||
272 | * | ||
273 | * Removes a notifier from a blocking notifier chain. | ||
274 | * Must be called from process context. | ||
275 | * | ||
276 | * Returns zero on success or %-ENOENT on failure. | ||
277 | */ | ||
278 | int blocking_notifier_chain_unregister(struct blocking_notifier_head *nh, | ||
279 | struct notifier_block *n) | ||
280 | { | ||
281 | int ret; | ||
282 | |||
283 | /* | ||
284 | * This code gets used during boot-up, when task switching is | ||
285 | * not yet working and interrupts must remain disabled. At | ||
286 | * such times we must not call down_write(). | ||
287 | */ | ||
288 | if (unlikely(system_state == SYSTEM_BOOTING)) | ||
289 | return notifier_chain_unregister(&nh->head, n); | ||
290 | |||
291 | down_write(&nh->rwsem); | ||
292 | ret = notifier_chain_unregister(&nh->head, n); | ||
293 | up_write(&nh->rwsem); | ||
294 | return ret; | ||
295 | } | ||
296 | |||
297 | EXPORT_SYMBOL_GPL(blocking_notifier_chain_unregister); | ||
298 | |||
299 | /** | ||
300 | * blocking_notifier_call_chain - Call functions in a blocking notifier chain | ||
301 | * @nh: Pointer to head of the blocking notifier chain | ||
160 | * @val: Value passed unmodified to notifier function | 302 | * @val: Value passed unmodified to notifier function |
161 | * @v: Pointer passed unmodified to notifier function | 303 | * @v: Pointer passed unmodified to notifier function |
162 | * | 304 | * |
163 | * Calls each function in a notifier chain in turn. | 305 | * Calls each function in a notifier chain in turn. The functions |
306 | * run in a process context, so they are allowed to block. | ||
164 | * | 307 | * |
165 | * If the return value of the notifier can be and'd | 308 | * If the return value of the notifier can be and'ed |
166 | * with %NOTIFY_STOP_MASK, then notifier_call_chain | 309 | * with %NOTIFY_STOP_MASK then blocking_notifier_call_chain |
167 | * will return immediately, with the return value of | 310 | * will return immediately, with the return value of |
168 | * the notifier function which halted execution. | 311 | * the notifier function which halted execution. |
169 | * Otherwise, the return value is the return value | 312 | * Otherwise the return value is the return value |
170 | * of the last notifier function called. | 313 | * of the last notifier function called. |
171 | */ | 314 | */ |
172 | 315 | ||
173 | int __kprobes notifier_call_chain(struct notifier_block **n, unsigned long val, void *v) | 316 | int blocking_notifier_call_chain(struct blocking_notifier_head *nh, |
317 | unsigned long val, void *v) | ||
174 | { | 318 | { |
175 | int ret=NOTIFY_DONE; | 319 | int ret; |
176 | struct notifier_block *nb = *n; | ||
177 | 320 | ||
178 | while(nb) | 321 | down_read(&nh->rwsem); |
179 | { | 322 | ret = notifier_call_chain(&nh->head, val, v); |
180 | ret=nb->notifier_call(nb,val,v); | 323 | up_read(&nh->rwsem); |
181 | if(ret&NOTIFY_STOP_MASK) | ||
182 | { | ||
183 | return ret; | ||
184 | } | ||
185 | nb=nb->next; | ||
186 | } | ||
187 | return ret; | 324 | return ret; |
188 | } | 325 | } |
189 | 326 | ||
190 | EXPORT_SYMBOL(notifier_call_chain); | 327 | EXPORT_SYMBOL_GPL(blocking_notifier_call_chain); |
328 | |||
329 | /* | ||
330 | * Raw notifier chain routines. There is no protection; | ||
331 | * the caller must provide it. Use at your own risk! | ||
332 | */ | ||
333 | |||
334 | /** | ||
335 | * raw_notifier_chain_register - Add notifier to a raw notifier chain | ||
336 | * @nh: Pointer to head of the raw notifier chain | ||
337 | * @n: New entry in notifier chain | ||
338 | * | ||
339 | * Adds a notifier to a raw notifier chain. | ||
340 | * All locking must be provided by the caller. | ||
341 | * | ||
342 | * Currently always returns zero. | ||
343 | */ | ||
344 | |||
345 | int raw_notifier_chain_register(struct raw_notifier_head *nh, | ||
346 | struct notifier_block *n) | ||
347 | { | ||
348 | return notifier_chain_register(&nh->head, n); | ||
349 | } | ||
350 | |||
351 | EXPORT_SYMBOL_GPL(raw_notifier_chain_register); | ||
352 | |||
353 | /** | ||
354 | * raw_notifier_chain_unregister - Remove notifier from a raw notifier chain | ||
355 | * @nh: Pointer to head of the raw notifier chain | ||
356 | * @n: Entry to remove from notifier chain | ||
357 | * | ||
358 | * Removes a notifier from a raw notifier chain. | ||
359 | * All locking must be provided by the caller. | ||
360 | * | ||
361 | * Returns zero on success or %-ENOENT on failure. | ||
362 | */ | ||
363 | int raw_notifier_chain_unregister(struct raw_notifier_head *nh, | ||
364 | struct notifier_block *n) | ||
365 | { | ||
366 | return notifier_chain_unregister(&nh->head, n); | ||
367 | } | ||
368 | |||
369 | EXPORT_SYMBOL_GPL(raw_notifier_chain_unregister); | ||
370 | |||
371 | /** | ||
372 | * raw_notifier_call_chain - Call functions in a raw notifier chain | ||
373 | * @nh: Pointer to head of the raw notifier chain | ||
374 | * @val: Value passed unmodified to notifier function | ||
375 | * @v: Pointer passed unmodified to notifier function | ||
376 | * | ||
377 | * Calls each function in a notifier chain in turn. The functions | ||
378 | * run in an undefined context. | ||
379 | * All locking must be provided by the caller. | ||
380 | * | ||
381 | * If the return value of the notifier can be and'ed | ||
382 | * with %NOTIFY_STOP_MASK then raw_notifier_call_chain | ||
383 | * will return immediately, with the return value of | ||
384 | * the notifier function which halted execution. | ||
385 | * Otherwise the return value is the return value | ||
386 | * of the last notifier function called. | ||
387 | */ | ||
388 | |||
389 | int raw_notifier_call_chain(struct raw_notifier_head *nh, | ||
390 | unsigned long val, void *v) | ||
391 | { | ||
392 | return notifier_call_chain(&nh->head, val, v); | ||
393 | } | ||
394 | |||
395 | EXPORT_SYMBOL_GPL(raw_notifier_call_chain); | ||
191 | 396 | ||
192 | /** | 397 | /** |
193 | * register_reboot_notifier - Register function to be called at reboot time | 398 | * register_reboot_notifier - Register function to be called at reboot time |
@@ -196,13 +401,13 @@ EXPORT_SYMBOL(notifier_call_chain); | |||
196 | * Registers a function with the list of functions | 401 | * Registers a function with the list of functions |
197 | * to be called at reboot time. | 402 | * to be called at reboot time. |
198 | * | 403 | * |
199 | * Currently always returns zero, as notifier_chain_register | 404 | * Currently always returns zero, as blocking_notifier_chain_register |
200 | * always returns zero. | 405 | * always returns zero. |
201 | */ | 406 | */ |
202 | 407 | ||
203 | int register_reboot_notifier(struct notifier_block * nb) | 408 | int register_reboot_notifier(struct notifier_block * nb) |
204 | { | 409 | { |
205 | return notifier_chain_register(&reboot_notifier_list, nb); | 410 | return blocking_notifier_chain_register(&reboot_notifier_list, nb); |
206 | } | 411 | } |
207 | 412 | ||
208 | EXPORT_SYMBOL(register_reboot_notifier); | 413 | EXPORT_SYMBOL(register_reboot_notifier); |
@@ -219,7 +424,7 @@ EXPORT_SYMBOL(register_reboot_notifier); | |||
219 | 424 | ||
220 | int unregister_reboot_notifier(struct notifier_block * nb) | 425 | int unregister_reboot_notifier(struct notifier_block * nb) |
221 | { | 426 | { |
222 | return notifier_chain_unregister(&reboot_notifier_list, nb); | 427 | return blocking_notifier_chain_unregister(&reboot_notifier_list, nb); |
223 | } | 428 | } |
224 | 429 | ||
225 | EXPORT_SYMBOL(unregister_reboot_notifier); | 430 | EXPORT_SYMBOL(unregister_reboot_notifier); |
@@ -380,7 +585,7 @@ EXPORT_SYMBOL_GPL(emergency_restart); | |||
380 | 585 | ||
381 | void kernel_restart_prepare(char *cmd) | 586 | void kernel_restart_prepare(char *cmd) |
382 | { | 587 | { |
383 | notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd); | 588 | blocking_notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd); |
384 | system_state = SYSTEM_RESTART; | 589 | system_state = SYSTEM_RESTART; |
385 | device_shutdown(); | 590 | device_shutdown(); |
386 | } | 591 | } |
@@ -430,7 +635,7 @@ EXPORT_SYMBOL_GPL(kernel_kexec); | |||
430 | 635 | ||
431 | void kernel_shutdown_prepare(enum system_states state) | 636 | void kernel_shutdown_prepare(enum system_states state) |
432 | { | 637 | { |
433 | notifier_call_chain(&reboot_notifier_list, | 638 | blocking_notifier_call_chain(&reboot_notifier_list, |
434 | (state == SYSTEM_HALT)?SYS_HALT:SYS_POWER_OFF, NULL); | 639 | (state == SYSTEM_HALT)?SYS_HALT:SYS_POWER_OFF, NULL); |
435 | system_state = state; | 640 | system_state = state; |
436 | device_shutdown(); | 641 | device_shutdown(); |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 9106354c781e..a49a6975092d 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -73,23 +73,23 @@ DEFINE_RWLOCK(hci_cb_list_lock); | |||
73 | struct hci_proto *hci_proto[HCI_MAX_PROTO]; | 73 | struct hci_proto *hci_proto[HCI_MAX_PROTO]; |
74 | 74 | ||
75 | /* HCI notifiers list */ | 75 | /* HCI notifiers list */ |
76 | static struct notifier_block *hci_notifier; | 76 | static ATOMIC_NOTIFIER_HEAD(hci_notifier); |
77 | 77 | ||
78 | /* ---- HCI notifications ---- */ | 78 | /* ---- HCI notifications ---- */ |
79 | 79 | ||
80 | int hci_register_notifier(struct notifier_block *nb) | 80 | int hci_register_notifier(struct notifier_block *nb) |
81 | { | 81 | { |
82 | return notifier_chain_register(&hci_notifier, nb); | 82 | return atomic_notifier_chain_register(&hci_notifier, nb); |
83 | } | 83 | } |
84 | 84 | ||
85 | int hci_unregister_notifier(struct notifier_block *nb) | 85 | int hci_unregister_notifier(struct notifier_block *nb) |
86 | { | 86 | { |
87 | return notifier_chain_unregister(&hci_notifier, nb); | 87 | return atomic_notifier_chain_unregister(&hci_notifier, nb); |
88 | } | 88 | } |
89 | 89 | ||
90 | static void hci_notify(struct hci_dev *hdev, int event) | 90 | static void hci_notify(struct hci_dev *hdev, int event) |
91 | { | 91 | { |
92 | notifier_call_chain(&hci_notifier, event, hdev); | 92 | atomic_notifier_call_chain(&hci_notifier, event, hdev); |
93 | } | 93 | } |
94 | 94 | ||
95 | /* ---- HCI requests ---- */ | 95 | /* ---- HCI requests ---- */ |
diff --git a/net/core/dev.c b/net/core/dev.c index 8e1dc3051222..a3ab11f34153 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -193,7 +193,7 @@ static inline struct hlist_head *dev_index_hash(int ifindex) | |||
193 | * Our notifier list | 193 | * Our notifier list |
194 | */ | 194 | */ |
195 | 195 | ||
196 | static struct notifier_block *netdev_chain; | 196 | static BLOCKING_NOTIFIER_HEAD(netdev_chain); |
197 | 197 | ||
198 | /* | 198 | /* |
199 | * Device drivers call our routines to queue packets here. We empty the | 199 | * Device drivers call our routines to queue packets here. We empty the |
@@ -736,7 +736,8 @@ int dev_change_name(struct net_device *dev, char *newname) | |||
736 | if (!err) { | 736 | if (!err) { |
737 | hlist_del(&dev->name_hlist); | 737 | hlist_del(&dev->name_hlist); |
738 | hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name)); | 738 | hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name)); |
739 | notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev); | 739 | blocking_notifier_call_chain(&netdev_chain, |
740 | NETDEV_CHANGENAME, dev); | ||
740 | } | 741 | } |
741 | 742 | ||
742 | return err; | 743 | return err; |
@@ -750,7 +751,7 @@ int dev_change_name(struct net_device *dev, char *newname) | |||
750 | */ | 751 | */ |
751 | void netdev_features_change(struct net_device *dev) | 752 | void netdev_features_change(struct net_device *dev) |
752 | { | 753 | { |
753 | notifier_call_chain(&netdev_chain, NETDEV_FEAT_CHANGE, dev); | 754 | blocking_notifier_call_chain(&netdev_chain, NETDEV_FEAT_CHANGE, dev); |
754 | } | 755 | } |
755 | EXPORT_SYMBOL(netdev_features_change); | 756 | EXPORT_SYMBOL(netdev_features_change); |
756 | 757 | ||
@@ -765,7 +766,8 @@ EXPORT_SYMBOL(netdev_features_change); | |||
765 | void netdev_state_change(struct net_device *dev) | 766 | void netdev_state_change(struct net_device *dev) |
766 | { | 767 | { |
767 | if (dev->flags & IFF_UP) { | 768 | if (dev->flags & IFF_UP) { |
768 | notifier_call_chain(&netdev_chain, NETDEV_CHANGE, dev); | 769 | blocking_notifier_call_chain(&netdev_chain, |
770 | NETDEV_CHANGE, dev); | ||
769 | rtmsg_ifinfo(RTM_NEWLINK, dev, 0); | 771 | rtmsg_ifinfo(RTM_NEWLINK, dev, 0); |
770 | } | 772 | } |
771 | } | 773 | } |
@@ -862,7 +864,7 @@ int dev_open(struct net_device *dev) | |||
862 | /* | 864 | /* |
863 | * ... and announce new interface. | 865 | * ... and announce new interface. |
864 | */ | 866 | */ |
865 | notifier_call_chain(&netdev_chain, NETDEV_UP, dev); | 867 | blocking_notifier_call_chain(&netdev_chain, NETDEV_UP, dev); |
866 | } | 868 | } |
867 | return ret; | 869 | return ret; |
868 | } | 870 | } |
@@ -885,7 +887,7 @@ int dev_close(struct net_device *dev) | |||
885 | * Tell people we are going down, so that they can | 887 | * Tell people we are going down, so that they can |
886 | * prepare to death, when device is still operating. | 888 | * prepare to death, when device is still operating. |
887 | */ | 889 | */ |
888 | notifier_call_chain(&netdev_chain, NETDEV_GOING_DOWN, dev); | 890 | blocking_notifier_call_chain(&netdev_chain, NETDEV_GOING_DOWN, dev); |
889 | 891 | ||
890 | dev_deactivate(dev); | 892 | dev_deactivate(dev); |
891 | 893 | ||
@@ -922,7 +924,7 @@ int dev_close(struct net_device *dev) | |||
922 | /* | 924 | /* |
923 | * Tell people we are down | 925 | * Tell people we are down |
924 | */ | 926 | */ |
925 | notifier_call_chain(&netdev_chain, NETDEV_DOWN, dev); | 927 | blocking_notifier_call_chain(&netdev_chain, NETDEV_DOWN, dev); |
926 | 928 | ||
927 | return 0; | 929 | return 0; |
928 | } | 930 | } |
@@ -953,7 +955,7 @@ int register_netdevice_notifier(struct notifier_block *nb) | |||
953 | int err; | 955 | int err; |
954 | 956 | ||
955 | rtnl_lock(); | 957 | rtnl_lock(); |
956 | err = notifier_chain_register(&netdev_chain, nb); | 958 | err = blocking_notifier_chain_register(&netdev_chain, nb); |
957 | if (!err) { | 959 | if (!err) { |
958 | for (dev = dev_base; dev; dev = dev->next) { | 960 | for (dev = dev_base; dev; dev = dev->next) { |
959 | nb->notifier_call(nb, NETDEV_REGISTER, dev); | 961 | nb->notifier_call(nb, NETDEV_REGISTER, dev); |
@@ -981,7 +983,7 @@ int unregister_netdevice_notifier(struct notifier_block *nb) | |||
981 | int err; | 983 | int err; |
982 | 984 | ||
983 | rtnl_lock(); | 985 | rtnl_lock(); |
984 | err = notifier_chain_unregister(&netdev_chain, nb); | 986 | err = blocking_notifier_chain_unregister(&netdev_chain, nb); |
985 | rtnl_unlock(); | 987 | rtnl_unlock(); |
986 | return err; | 988 | return err; |
987 | } | 989 | } |
@@ -992,12 +994,12 @@ int unregister_netdevice_notifier(struct notifier_block *nb) | |||
992 | * @v: pointer passed unmodified to notifier function | 994 | * @v: pointer passed unmodified to notifier function |
993 | * | 995 | * |
994 | * Call all network notifier blocks. Parameters and return value | 996 | * Call all network notifier blocks. Parameters and return value |
995 | * are as for notifier_call_chain(). | 997 | * are as for blocking_notifier_call_chain(). |
996 | */ | 998 | */ |
997 | 999 | ||
998 | int call_netdevice_notifiers(unsigned long val, void *v) | 1000 | int call_netdevice_notifiers(unsigned long val, void *v) |
999 | { | 1001 | { |
1000 | return notifier_call_chain(&netdev_chain, val, v); | 1002 | return blocking_notifier_call_chain(&netdev_chain, val, v); |
1001 | } | 1003 | } |
1002 | 1004 | ||
1003 | /* When > 0 there are consumers of rx skb time stamps */ | 1005 | /* When > 0 there are consumers of rx skb time stamps */ |
@@ -2242,7 +2244,8 @@ int dev_change_flags(struct net_device *dev, unsigned flags) | |||
2242 | if (dev->flags & IFF_UP && | 2244 | if (dev->flags & IFF_UP && |
2243 | ((old_flags ^ dev->flags) &~ (IFF_UP | IFF_PROMISC | IFF_ALLMULTI | | 2245 | ((old_flags ^ dev->flags) &~ (IFF_UP | IFF_PROMISC | IFF_ALLMULTI | |
2244 | IFF_VOLATILE))) | 2246 | IFF_VOLATILE))) |
2245 | notifier_call_chain(&netdev_chain, NETDEV_CHANGE, dev); | 2247 | blocking_notifier_call_chain(&netdev_chain, |
2248 | NETDEV_CHANGE, dev); | ||
2246 | 2249 | ||
2247 | if ((flags ^ dev->gflags) & IFF_PROMISC) { | 2250 | if ((flags ^ dev->gflags) & IFF_PROMISC) { |
2248 | int inc = (flags & IFF_PROMISC) ? +1 : -1; | 2251 | int inc = (flags & IFF_PROMISC) ? +1 : -1; |
@@ -2286,8 +2289,8 @@ int dev_set_mtu(struct net_device *dev, int new_mtu) | |||
2286 | else | 2289 | else |
2287 | dev->mtu = new_mtu; | 2290 | dev->mtu = new_mtu; |
2288 | if (!err && dev->flags & IFF_UP) | 2291 | if (!err && dev->flags & IFF_UP) |
2289 | notifier_call_chain(&netdev_chain, | 2292 | blocking_notifier_call_chain(&netdev_chain, |
2290 | NETDEV_CHANGEMTU, dev); | 2293 | NETDEV_CHANGEMTU, dev); |
2291 | return err; | 2294 | return err; |
2292 | } | 2295 | } |
2293 | 2296 | ||
@@ -2303,7 +2306,8 @@ int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa) | |||
2303 | return -ENODEV; | 2306 | return -ENODEV; |
2304 | err = dev->set_mac_address(dev, sa); | 2307 | err = dev->set_mac_address(dev, sa); |
2305 | if (!err) | 2308 | if (!err) |
2306 | notifier_call_chain(&netdev_chain, NETDEV_CHANGEADDR, dev); | 2309 | blocking_notifier_call_chain(&netdev_chain, |
2310 | NETDEV_CHANGEADDR, dev); | ||
2307 | return err; | 2311 | return err; |
2308 | } | 2312 | } |
2309 | 2313 | ||
@@ -2359,7 +2363,7 @@ static int dev_ifsioc(struct ifreq *ifr, unsigned int cmd) | |||
2359 | return -EINVAL; | 2363 | return -EINVAL; |
2360 | memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data, | 2364 | memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data, |
2361 | min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len)); | 2365 | min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len)); |
2362 | notifier_call_chain(&netdev_chain, | 2366 | blocking_notifier_call_chain(&netdev_chain, |
2363 | NETDEV_CHANGEADDR, dev); | 2367 | NETDEV_CHANGEADDR, dev); |
2364 | return 0; | 2368 | return 0; |
2365 | 2369 | ||
@@ -2813,7 +2817,7 @@ int register_netdevice(struct net_device *dev) | |||
2813 | write_unlock_bh(&dev_base_lock); | 2817 | write_unlock_bh(&dev_base_lock); |
2814 | 2818 | ||
2815 | /* Notify protocols, that a new device appeared. */ | 2819 | /* Notify protocols, that a new device appeared. */ |
2816 | notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev); | 2820 | blocking_notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev); |
2817 | 2821 | ||
2818 | /* Finish registration after unlock */ | 2822 | /* Finish registration after unlock */ |
2819 | net_set_todo(dev); | 2823 | net_set_todo(dev); |
@@ -2892,7 +2896,7 @@ static void netdev_wait_allrefs(struct net_device *dev) | |||
2892 | rtnl_lock(); | 2896 | rtnl_lock(); |
2893 | 2897 | ||
2894 | /* Rebroadcast unregister notification */ | 2898 | /* Rebroadcast unregister notification */ |
2895 | notifier_call_chain(&netdev_chain, | 2899 | blocking_notifier_call_chain(&netdev_chain, |
2896 | NETDEV_UNREGISTER, dev); | 2900 | NETDEV_UNREGISTER, dev); |
2897 | 2901 | ||
2898 | if (test_bit(__LINK_STATE_LINKWATCH_PENDING, | 2902 | if (test_bit(__LINK_STATE_LINKWATCH_PENDING, |
@@ -3148,7 +3152,7 @@ int unregister_netdevice(struct net_device *dev) | |||
3148 | /* Notify protocols, that we are about to destroy | 3152 | /* Notify protocols, that we are about to destroy |
3149 | this device. They should clean all the things. | 3153 | this device. They should clean all the things. |
3150 | */ | 3154 | */ |
3151 | notifier_call_chain(&netdev_chain, NETDEV_UNREGISTER, dev); | 3155 | blocking_notifier_call_chain(&netdev_chain, NETDEV_UNREGISTER, dev); |
3152 | 3156 | ||
3153 | /* | 3157 | /* |
3154 | * Flush the multicast chain | 3158 | * Flush the multicast chain |
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index cc7b9d9255ef..d2ae9893ca17 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c | |||
@@ -68,7 +68,7 @@ __le16 decnet_address = 0; | |||
68 | 68 | ||
69 | static DEFINE_RWLOCK(dndev_lock); | 69 | static DEFINE_RWLOCK(dndev_lock); |
70 | static struct net_device *decnet_default_device; | 70 | static struct net_device *decnet_default_device; |
71 | static struct notifier_block *dnaddr_chain; | 71 | static BLOCKING_NOTIFIER_HEAD(dnaddr_chain); |
72 | 72 | ||
73 | static struct dn_dev *dn_dev_create(struct net_device *dev, int *err); | 73 | static struct dn_dev *dn_dev_create(struct net_device *dev, int *err); |
74 | static void dn_dev_delete(struct net_device *dev); | 74 | static void dn_dev_delete(struct net_device *dev); |
@@ -446,7 +446,7 @@ static void dn_dev_del_ifa(struct dn_dev *dn_db, struct dn_ifaddr **ifap, int de | |||
446 | } | 446 | } |
447 | 447 | ||
448 | rtmsg_ifa(RTM_DELADDR, ifa1); | 448 | rtmsg_ifa(RTM_DELADDR, ifa1); |
449 | notifier_call_chain(&dnaddr_chain, NETDEV_DOWN, ifa1); | 449 | blocking_notifier_call_chain(&dnaddr_chain, NETDEV_DOWN, ifa1); |
450 | if (destroy) { | 450 | if (destroy) { |
451 | dn_dev_free_ifa(ifa1); | 451 | dn_dev_free_ifa(ifa1); |
452 | 452 | ||
@@ -481,7 +481,7 @@ static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa) | |||
481 | dn_db->ifa_list = ifa; | 481 | dn_db->ifa_list = ifa; |
482 | 482 | ||
483 | rtmsg_ifa(RTM_NEWADDR, ifa); | 483 | rtmsg_ifa(RTM_NEWADDR, ifa); |
484 | notifier_call_chain(&dnaddr_chain, NETDEV_UP, ifa); | 484 | blocking_notifier_call_chain(&dnaddr_chain, NETDEV_UP, ifa); |
485 | 485 | ||
486 | return 0; | 486 | return 0; |
487 | } | 487 | } |
@@ -1285,12 +1285,12 @@ void dn_dev_devices_on(void) | |||
1285 | 1285 | ||
1286 | int register_dnaddr_notifier(struct notifier_block *nb) | 1286 | int register_dnaddr_notifier(struct notifier_block *nb) |
1287 | { | 1287 | { |
1288 | return notifier_chain_register(&dnaddr_chain, nb); | 1288 | return blocking_notifier_chain_register(&dnaddr_chain, nb); |
1289 | } | 1289 | } |
1290 | 1290 | ||
1291 | int unregister_dnaddr_notifier(struct notifier_block *nb) | 1291 | int unregister_dnaddr_notifier(struct notifier_block *nb) |
1292 | { | 1292 | { |
1293 | return notifier_chain_unregister(&dnaddr_chain, nb); | 1293 | return blocking_notifier_chain_unregister(&dnaddr_chain, nb); |
1294 | } | 1294 | } |
1295 | 1295 | ||
1296 | #ifdef CONFIG_PROC_FS | 1296 | #ifdef CONFIG_PROC_FS |
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 44fdf1413e2c..81c2f7885292 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -81,7 +81,7 @@ static struct ipv4_devconf ipv4_devconf_dflt = { | |||
81 | 81 | ||
82 | static void rtmsg_ifa(int event, struct in_ifaddr *); | 82 | static void rtmsg_ifa(int event, struct in_ifaddr *); |
83 | 83 | ||
84 | static struct notifier_block *inetaddr_chain; | 84 | static BLOCKING_NOTIFIER_HEAD(inetaddr_chain); |
85 | static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, | 85 | static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, |
86 | int destroy); | 86 | int destroy); |
87 | #ifdef CONFIG_SYSCTL | 87 | #ifdef CONFIG_SYSCTL |
@@ -267,7 +267,8 @@ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, | |||
267 | *ifap1 = ifa->ifa_next; | 267 | *ifap1 = ifa->ifa_next; |
268 | 268 | ||
269 | rtmsg_ifa(RTM_DELADDR, ifa); | 269 | rtmsg_ifa(RTM_DELADDR, ifa); |
270 | notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa); | 270 | blocking_notifier_call_chain(&inetaddr_chain, |
271 | NETDEV_DOWN, ifa); | ||
271 | inet_free_ifa(ifa); | 272 | inet_free_ifa(ifa); |
272 | } else { | 273 | } else { |
273 | promote = ifa; | 274 | promote = ifa; |
@@ -291,7 +292,7 @@ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, | |||
291 | So that, this order is correct. | 292 | So that, this order is correct. |
292 | */ | 293 | */ |
293 | rtmsg_ifa(RTM_DELADDR, ifa1); | 294 | rtmsg_ifa(RTM_DELADDR, ifa1); |
294 | notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa1); | 295 | blocking_notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa1); |
295 | 296 | ||
296 | if (promote) { | 297 | if (promote) { |
297 | 298 | ||
@@ -303,7 +304,8 @@ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, | |||
303 | 304 | ||
304 | promote->ifa_flags &= ~IFA_F_SECONDARY; | 305 | promote->ifa_flags &= ~IFA_F_SECONDARY; |
305 | rtmsg_ifa(RTM_NEWADDR, promote); | 306 | rtmsg_ifa(RTM_NEWADDR, promote); |
306 | notifier_call_chain(&inetaddr_chain, NETDEV_UP, promote); | 307 | blocking_notifier_call_chain(&inetaddr_chain, |
308 | NETDEV_UP, promote); | ||
307 | for (ifa = promote->ifa_next; ifa; ifa = ifa->ifa_next) { | 309 | for (ifa = promote->ifa_next; ifa; ifa = ifa->ifa_next) { |
308 | if (ifa1->ifa_mask != ifa->ifa_mask || | 310 | if (ifa1->ifa_mask != ifa->ifa_mask || |
309 | !inet_ifa_match(ifa1->ifa_address, ifa)) | 311 | !inet_ifa_match(ifa1->ifa_address, ifa)) |
@@ -366,7 +368,7 @@ static int inet_insert_ifa(struct in_ifaddr *ifa) | |||
366 | Notifier will trigger FIB update, so that | 368 | Notifier will trigger FIB update, so that |
367 | listeners of netlink will know about new ifaddr */ | 369 | listeners of netlink will know about new ifaddr */ |
368 | rtmsg_ifa(RTM_NEWADDR, ifa); | 370 | rtmsg_ifa(RTM_NEWADDR, ifa); |
369 | notifier_call_chain(&inetaddr_chain, NETDEV_UP, ifa); | 371 | blocking_notifier_call_chain(&inetaddr_chain, NETDEV_UP, ifa); |
370 | 372 | ||
371 | return 0; | 373 | return 0; |
372 | } | 374 | } |
@@ -938,12 +940,12 @@ u32 inet_confirm_addr(const struct net_device *dev, u32 dst, u32 local, int scop | |||
938 | 940 | ||
939 | int register_inetaddr_notifier(struct notifier_block *nb) | 941 | int register_inetaddr_notifier(struct notifier_block *nb) |
940 | { | 942 | { |
941 | return notifier_chain_register(&inetaddr_chain, nb); | 943 | return blocking_notifier_chain_register(&inetaddr_chain, nb); |
942 | } | 944 | } |
943 | 945 | ||
944 | int unregister_inetaddr_notifier(struct notifier_block *nb) | 946 | int unregister_inetaddr_notifier(struct notifier_block *nb) |
945 | { | 947 | { |
946 | return notifier_chain_unregister(&inetaddr_chain, nb); | 948 | return blocking_notifier_chain_unregister(&inetaddr_chain, nb); |
947 | } | 949 | } |
948 | 950 | ||
949 | /* Rename ifa_labels for a device name change. Make some effort to preserve existing | 951 | /* Rename ifa_labels for a device name change. Make some effort to preserve existing |
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c index 9e34034729a6..ceaabc18202b 100644 --- a/net/ipv4/netfilter/ip_conntrack_core.c +++ b/net/ipv4/netfilter/ip_conntrack_core.c | |||
@@ -80,8 +80,8 @@ static int ip_conntrack_vmalloc; | |||
80 | static unsigned int ip_conntrack_next_id; | 80 | static unsigned int ip_conntrack_next_id; |
81 | static unsigned int ip_conntrack_expect_next_id; | 81 | static unsigned int ip_conntrack_expect_next_id; |
82 | #ifdef CONFIG_IP_NF_CONNTRACK_EVENTS | 82 | #ifdef CONFIG_IP_NF_CONNTRACK_EVENTS |
83 | struct notifier_block *ip_conntrack_chain; | 83 | ATOMIC_NOTIFIER_HEAD(ip_conntrack_chain); |
84 | struct notifier_block *ip_conntrack_expect_chain; | 84 | ATOMIC_NOTIFIER_HEAD(ip_conntrack_expect_chain); |
85 | 85 | ||
86 | DEFINE_PER_CPU(struct ip_conntrack_ecache, ip_conntrack_ecache); | 86 | DEFINE_PER_CPU(struct ip_conntrack_ecache, ip_conntrack_ecache); |
87 | 87 | ||
@@ -92,7 +92,7 @@ __ip_ct_deliver_cached_events(struct ip_conntrack_ecache *ecache) | |||
92 | { | 92 | { |
93 | DEBUGP("ecache: delivering events for %p\n", ecache->ct); | 93 | DEBUGP("ecache: delivering events for %p\n", ecache->ct); |
94 | if (is_confirmed(ecache->ct) && !is_dying(ecache->ct) && ecache->events) | 94 | if (is_confirmed(ecache->ct) && !is_dying(ecache->ct) && ecache->events) |
95 | notifier_call_chain(&ip_conntrack_chain, ecache->events, | 95 | atomic_notifier_call_chain(&ip_conntrack_chain, ecache->events, |
96 | ecache->ct); | 96 | ecache->ct); |
97 | ecache->events = 0; | 97 | ecache->events = 0; |
98 | ip_conntrack_put(ecache->ct); | 98 | ip_conntrack_put(ecache->ct); |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 01c62a0d3742..445006ee4522 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -143,7 +143,7 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev, | |||
143 | struct prefix_info *pinfo); | 143 | struct prefix_info *pinfo); |
144 | static int ipv6_chk_same_addr(const struct in6_addr *addr, struct net_device *dev); | 144 | static int ipv6_chk_same_addr(const struct in6_addr *addr, struct net_device *dev); |
145 | 145 | ||
146 | static struct notifier_block *inet6addr_chain; | 146 | static ATOMIC_NOTIFIER_HEAD(inet6addr_chain); |
147 | 147 | ||
148 | struct ipv6_devconf ipv6_devconf = { | 148 | struct ipv6_devconf ipv6_devconf = { |
149 | .forwarding = 0, | 149 | .forwarding = 0, |
@@ -593,7 +593,7 @@ out2: | |||
593 | read_unlock_bh(&addrconf_lock); | 593 | read_unlock_bh(&addrconf_lock); |
594 | 594 | ||
595 | if (likely(err == 0)) | 595 | if (likely(err == 0)) |
596 | notifier_call_chain(&inet6addr_chain, NETDEV_UP, ifa); | 596 | atomic_notifier_call_chain(&inet6addr_chain, NETDEV_UP, ifa); |
597 | else { | 597 | else { |
598 | kfree(ifa); | 598 | kfree(ifa); |
599 | ifa = ERR_PTR(err); | 599 | ifa = ERR_PTR(err); |
@@ -688,7 +688,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) | |||
688 | 688 | ||
689 | ipv6_ifa_notify(RTM_DELADDR, ifp); | 689 | ipv6_ifa_notify(RTM_DELADDR, ifp); |
690 | 690 | ||
691 | notifier_call_chain(&inet6addr_chain,NETDEV_DOWN,ifp); | 691 | atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifp); |
692 | 692 | ||
693 | addrconf_del_timer(ifp); | 693 | addrconf_del_timer(ifp); |
694 | 694 | ||
@@ -3767,12 +3767,12 @@ static void addrconf_sysctl_unregister(struct ipv6_devconf *p) | |||
3767 | 3767 | ||
3768 | int register_inet6addr_notifier(struct notifier_block *nb) | 3768 | int register_inet6addr_notifier(struct notifier_block *nb) |
3769 | { | 3769 | { |
3770 | return notifier_chain_register(&inet6addr_chain, nb); | 3770 | return atomic_notifier_chain_register(&inet6addr_chain, nb); |
3771 | } | 3771 | } |
3772 | 3772 | ||
3773 | int unregister_inet6addr_notifier(struct notifier_block *nb) | 3773 | int unregister_inet6addr_notifier(struct notifier_block *nb) |
3774 | { | 3774 | { |
3775 | return notifier_chain_unregister(&inet6addr_chain,nb); | 3775 | return atomic_notifier_chain_unregister(&inet6addr_chain,nb); |
3776 | } | 3776 | } |
3777 | 3777 | ||
3778 | /* | 3778 | /* |
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 0ae281d9bfc3..56389c83557c 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
@@ -90,8 +90,8 @@ static int nf_conntrack_vmalloc; | |||
90 | static unsigned int nf_conntrack_next_id; | 90 | static unsigned int nf_conntrack_next_id; |
91 | static unsigned int nf_conntrack_expect_next_id; | 91 | static unsigned int nf_conntrack_expect_next_id; |
92 | #ifdef CONFIG_NF_CONNTRACK_EVENTS | 92 | #ifdef CONFIG_NF_CONNTRACK_EVENTS |
93 | struct notifier_block *nf_conntrack_chain; | 93 | ATOMIC_NOTIFIER_HEAD(nf_conntrack_chain); |
94 | struct notifier_block *nf_conntrack_expect_chain; | 94 | ATOMIC_NOTIFIER_HEAD(nf_conntrack_expect_chain); |
95 | 95 | ||
96 | DEFINE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache); | 96 | DEFINE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache); |
97 | 97 | ||
@@ -103,7 +103,7 @@ __nf_ct_deliver_cached_events(struct nf_conntrack_ecache *ecache) | |||
103 | DEBUGP("ecache: delivering events for %p\n", ecache->ct); | 103 | DEBUGP("ecache: delivering events for %p\n", ecache->ct); |
104 | if (nf_ct_is_confirmed(ecache->ct) && !nf_ct_is_dying(ecache->ct) | 104 | if (nf_ct_is_confirmed(ecache->ct) && !nf_ct_is_dying(ecache->ct) |
105 | && ecache->events) | 105 | && ecache->events) |
106 | notifier_call_chain(&nf_conntrack_chain, ecache->events, | 106 | atomic_notifier_call_chain(&nf_conntrack_chain, ecache->events, |
107 | ecache->ct); | 107 | ecache->ct); |
108 | 108 | ||
109 | ecache->events = 0; | 109 | ecache->events = 0; |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index d00a9034cb5f..2a233ffcf618 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -123,7 +123,7 @@ static void netlink_destroy_callback(struct netlink_callback *cb); | |||
123 | static DEFINE_RWLOCK(nl_table_lock); | 123 | static DEFINE_RWLOCK(nl_table_lock); |
124 | static atomic_t nl_table_users = ATOMIC_INIT(0); | 124 | static atomic_t nl_table_users = ATOMIC_INIT(0); |
125 | 125 | ||
126 | static struct notifier_block *netlink_chain; | 126 | static ATOMIC_NOTIFIER_HEAD(netlink_chain); |
127 | 127 | ||
128 | static u32 netlink_group_mask(u32 group) | 128 | static u32 netlink_group_mask(u32 group) |
129 | { | 129 | { |
@@ -469,7 +469,8 @@ static int netlink_release(struct socket *sock) | |||
469 | .protocol = sk->sk_protocol, | 469 | .protocol = sk->sk_protocol, |
470 | .pid = nlk->pid, | 470 | .pid = nlk->pid, |
471 | }; | 471 | }; |
472 | notifier_call_chain(&netlink_chain, NETLINK_URELEASE, &n); | 472 | atomic_notifier_call_chain(&netlink_chain, |
473 | NETLINK_URELEASE, &n); | ||
473 | } | 474 | } |
474 | 475 | ||
475 | if (nlk->module) | 476 | if (nlk->module) |
@@ -1695,12 +1696,12 @@ static struct file_operations netlink_seq_fops = { | |||
1695 | 1696 | ||
1696 | int netlink_register_notifier(struct notifier_block *nb) | 1697 | int netlink_register_notifier(struct notifier_block *nb) |
1697 | { | 1698 | { |
1698 | return notifier_chain_register(&netlink_chain, nb); | 1699 | return atomic_notifier_chain_register(&netlink_chain, nb); |
1699 | } | 1700 | } |
1700 | 1701 | ||
1701 | int netlink_unregister_notifier(struct notifier_block *nb) | 1702 | int netlink_unregister_notifier(struct notifier_block *nb) |
1702 | { | 1703 | { |
1703 | return notifier_chain_unregister(&netlink_chain, nb); | 1704 | return atomic_notifier_chain_unregister(&netlink_chain, nb); |
1704 | } | 1705 | } |
1705 | 1706 | ||
1706 | static const struct proto_ops netlink_ops = { | 1707 | static const struct proto_ops netlink_ops = { |