Re: [PATCH 01/12] notifier: add device-managed registration APIs
From: Bartosz Golaszewski
Date: Fri Jul 24 2026 - 03:47:26 EST
On Thu, 23 Jul 2026 19:53:14 +0200, Eliav Farber <farbere@xxxxxxxxxx> said:
> Add devm_atomic_notifier_chain_register(),
> devm_blocking_notifier_chain_register(), and
> devm_raw_notifier_chain_register() that automatically unregister the
> notifier when the device is unbound.
>
> Many drivers repeat the same boilerplate pattern:
>
> 1. Register the notifier with *_notifier_chain_register()
> 2. Check for error
> 3. Register a devm action to unregister on teardown
> 4. Implement a per-driver static unregister callback
>
> With the new devm_*_notifier_chain_register() APIs, this reduces to a
> single call with one error path, eliminating per-driver unregister
> callbacks entirely.
>
> The implementation follows the established devres pattern used by other
> device-managed kernel APIs.
>
> Signed-off-by: Eliav Farber <farbere@xxxxxxxxxx>
> ---
> include/linux/notifier.h | 10 +++
> kernel/notifier.c | 151 +++++++++++++++++++++++++++++++++++++++
> 2 files changed, 161 insertions(+)
>
> diff --git a/include/linux/notifier.h b/include/linux/notifier.h
> index 01b6c9d9956f..aa3745d7459b 100644
> --- a/include/linux/notifier.h
> +++ b/include/linux/notifier.h
> @@ -46,6 +46,7 @@
> * often but notifier_blocks will seldom be removed.
> */
>
> +struct device;
> struct notifier_block;
>
> typedef int (*notifier_fn_t)(struct notifier_block *nb,
> @@ -145,10 +146,19 @@ extern void srcu_init_notifier_head(struct srcu_notifier_head *nh);
>
> extern int atomic_notifier_chain_register(struct atomic_notifier_head *nh,
> struct notifier_block *nb);
> +extern int devm_atomic_notifier_chain_register(struct device *dev,
> + struct atomic_notifier_head *nh,
> + struct notifier_block *nb);
Please don't use extern with function prototypes in new code.
> extern int blocking_notifier_chain_register(struct blocking_notifier_head *nh,
> struct notifier_block *nb);
> +extern int devm_blocking_notifier_chain_register(struct device *dev,
> + struct blocking_notifier_head *nh,
> + struct notifier_block *nb);
> extern int raw_notifier_chain_register(struct raw_notifier_head *nh,
> struct notifier_block *nb);
> +extern int devm_raw_notifier_chain_register(struct device *dev,
> + struct raw_notifier_head *nh,
> + struct notifier_block *nb);
> extern int srcu_notifier_chain_register(struct srcu_notifier_head *nh,
> struct notifier_block *nb);
>
> diff --git a/kernel/notifier.c b/kernel/notifier.c
> index 2f9fe7c30287..b811638aa878 100644
> --- a/kernel/notifier.c
> +++ b/kernel/notifier.c
> @@ -1,4 +1,5 @@
> // SPDX-License-Identifier: GPL-2.0-only
> +#include <linux/device.h>
> #include <linux/kdebug.h>
> #include <linux/kprobes.h>
> #include <linux/export.h>
> @@ -197,6 +198,55 @@ int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh,
> }
> EXPORT_SYMBOL_GPL(atomic_notifier_chain_unregister);
>
> +struct atomic_notifier_chain_devres {
> + struct atomic_notifier_head *nh;
> + struct notifier_block *nb;
> +};
> +
> +static void devm_atomic_notifier_chain_unregister(struct device *dev, void *res)
> +{
> + struct atomic_notifier_chain_devres *dr = res;
> +
> + atomic_notifier_chain_unregister(dr->nh, dr->nb);
> +}
> +
> +/**
> + * devm_atomic_notifier_chain_register - Device-managed atomic notifier registration
> + * @dev: Device to tie the notifier lifetime to
> + * @nh: Pointer to head of the atomic notifier chain
> + * @n: New entry in notifier chain
> + *
> + * Adds a notifier to an atomic notifier chain and registers a cleanup
> + * action to automatically unregister it when @dev is unbound.
> + *
> + * Returns 0 on success, negative errno on error.
Should be:
Returns:
0 on success...
Bart