Re: [PATCH] clk: fix possible circular locking in clk_notifier_register()

From: Sean Nyekjaer
Date: Thu Jun 10 2021 - 03:23:49 EST


On 10/06/2021 09.17, Sean Nyekjaer wrote:
> Allocating memory with prepare_lock mutex held makes lockdep unhappy
> when memory pressure makes the system do fs_reclaim on eg. rawnand using
> clk.
>
> Push the allocation outside the lock.
>
[...]
>
> Signed-off-by: Sean Nyekjaer <sean@xxxxxxxxxx>
Fixes: b2476490ef111 ("clk: introduce the common clock framework")

We could possibly add this fixes tag ^^
> ---
> drivers/clk/clk.c | 17 ++++++++++-------
> 1 file changed, 10 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index 65508eb89ec9..c32b71b08ccb 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -4340,17 +4340,20 @@ int clk_notifier_register(struct clk *clk, struct notifier_block *nb)
> if (!clk || !nb)
> return -EINVAL;
>
> + /* allocate new clk_notifier */
> + cn = kzalloc(sizeof(*cn), GFP_KERNEL);
> + if (!cn)
> + goto out;
> +
> clk_prepare_lock();
>
> /* search the list of notifiers for this clk */
> list_for_each_entry(cn, &clk_notifier_list, node)
> - if (cn->clk == clk)
> + if (cn->clk == clk) {
> + /* if clk is in the notifier list, free new clk_notifier */
> + kfree(cn);
> goto found;
> -
> - /* if clk wasn't in the notifier list, allocate new clk_notifier */
> - cn = kzalloc(sizeof(*cn), GFP_KERNEL);
> - if (!cn)
> - goto out;
> + }
>
> cn->clk = clk;
> srcu_init_notifier_head(&cn->notifier_head);
> @@ -4362,9 +4365,9 @@ int clk_notifier_register(struct clk *clk, struct notifier_block *nb)
>
> clk->core->notifier_count++;
>
> -out:
> clk_prepare_unlock();
>
> +out:
> return ret;
> }
> EXPORT_SYMBOL_GPL(clk_notifier_register);
>