Return -EEXIST when a notifier callback has already been registered on a notifier chain. This should avoid any homegrown registration tracking at the callsite like https://lore.kernel.org/amd-gfx/20210512013058.6827-1-mukul.joshi@amd.com for example. This version is an alternative of https://lore.kernel.org/r/20211108101157.15189-1-bp@alien8.de which needed to touch every caller not checking the registration routine's return value.
Showing the changes to kernel (1 of 1 file). Show all
Unified · Split
| @@ -20,12 +20,13 @@ BLOCKING_NOTIFIER_HEAD(reboot_notifier_list); · 19 unmodified lines | ||
| 20 | 20 | */ |
| 21 | 21 | |
| 22 | 22 | static int notifier_chain_register(struct notifier_block **nl, |
| 23 | − struct notifier_block *n) | |
| 23 | + struct notifier_block *n) | |
| 24 | 24 | { |
| 25 | 25 | while ((*nl) != NULL) { |
| 26 | 26 | if (unlikely((*nl) == n)) { |
| 27 | − WARN(1, "double register detected"); | |
| 28 | − return 0; | |
| 27 | + WARN(1, "notifier callback %ps already registered", | |
| 28 | + n->notifier_call); | |
| 29 | + return -EEXIST; | |
| 29 | 30 | } |
| 30 | 31 | if (n->priority > (*nl)->priority) |
| 31 | 32 | break; |
| @@ -134,7 +135,7 @@ static int notifier_call_chain_robust(struct notifier_block **nl, · 102 unmodified lines | ||
| 134 | 135 | * |
| 135 | 136 | * Adds a notifier to an atomic notifier chain. |
| 136 | 137 | * |
| 137 | − * Currently always returns zero. | |
| 138 | + * Returns 0 on success, %-EEXIST on error. | |
| 138 | 139 | */ |
| 139 | 140 | int atomic_notifier_chain_register(struct atomic_notifier_head *nh, |
| 140 | 141 | struct notifier_block *n) |
| @@ -216,7 +217,7 @@ NOKPROBE_SYMBOL(atomic_notifier_call_chain); · 75 unmodified lines | ||
| 216 | 217 | * Adds a notifier to a blocking notifier chain. |
| 217 | 218 | * Must be called in process context. |
| 218 | 219 | * |
| 219 | − * Currently always returns zero. | |
| 220 | + * Returns 0 on success, %-EEXIST on error. | |
| 220 | 221 | */ |
| 221 | 222 | int blocking_notifier_chain_register(struct blocking_notifier_head *nh, |
| 222 | 223 | struct notifier_block *n) |
| @@ -335,7 +336,7 @@ EXPORT_SYMBOL_GPL(blocking_notifier_call_chain); · 112 unmodified lines | ||
| 335 | 336 | * Adds a notifier to a raw notifier chain. |
| 336 | 337 | * All locking must be provided by the caller. |
| 337 | 338 | * |
| 338 | − * Currently always returns zero. | |
| 339 | + * Returns 0 on success, %-EEXIST on error. | |
| 339 | 340 | */ |
| 340 | 341 | int raw_notifier_chain_register(struct raw_notifier_head *nh, |
| 341 | 342 | struct notifier_block *n) |
| @@ -406,7 +407,7 @@ EXPORT_SYMBOL_GPL(raw_notifier_call_chain); · 64 unmodified lines | ||
| 406 | 407 | * Adds a notifier to an SRCU notifier chain. |
| 407 | 408 | * Must be called in process context. |
| 408 | 409 | * |
| 409 | − * Currently always returns zero. | |
| 410 | + * Returns 0 on success, %-EEXIST on error. | |
| 410 | 411 | */ |
| 411 | 412 | int srcu_notifier_chain_register(struct srcu_notifier_head *nh, |
| 412 | 413 | struct notifier_block *n) |