From: Frank Rowand <frowand.list@gmail.com>
To: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: devicetree@vger.kernel.org, Rob Herring <robh+dt@kernel.org>,
Thomas Gleixner <tglx@linutronix.de>
Subject: Re: [PATCH v2] of: allocate / free phandle cache outside of the devtree_lock
Date: Fri, 29 Nov 2019 20:46:31 -0600 [thread overview]
Message-ID: <14b65198-fea8-377c-2147-86cb2680bee2@gmail.com> (raw)
In-Reply-To: <20191129140446.dqb5y4uzv57cislp@linutronix.de>
On 11/29/19 8:04 AM, Sebastian Andrzej Siewior wrote:
> The phandle cache code allocates memory while holding devtree_lock which
> is a raw_spinlock_t. Memory allocation (and free()) is not possible on
> RT while a raw_spinlock_t is held.
> Invoke the kfree() and kcalloc() while the lock is dropped.
>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Frank Rowand <frowand.list@gmail.com>
> Cc: devicetree@vger.kernel.org
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> ---
> v1…v2:
> - Add comments regarding memory allocation under the raw_spinlock_t
> - use a temporary variable for the memory allocation.
>
> drivers/of/base.c | 32 +++++++++++++++++++++++---------
> 1 file changed, 23 insertions(+), 9 deletions(-)
>
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -136,33 +136,37 @@ static struct device_node **phandle_cach
> static u32 phandle_cache_mask;
>
> /*
> - * Caller must hold devtree_lock.
> + * Caller must hold devtree_lock under which kfree() can't be used so caller
> + * needs to kfree() the returned pointer.
> */
> -static void __of_free_phandle_cache(void)
> +static struct device_node **__of_free_phandle_cache(void)
> {
> u32 cache_entries = phandle_cache_mask + 1;
> u32 k;
> + struct device_node **shadow;
>
> if (!phandle_cache)
> - return;
> + return NULL;
>
> for (k = 0; k < cache_entries; k++)
> of_node_put(phandle_cache[k]);
>
> - kfree(phandle_cache);
> + shadow = phandle_cache;
> phandle_cache = NULL;
> + return shadow;
> }
>
> int of_free_phandle_cache(void)
> {
> unsigned long flags;
> + struct device_node **shadow;
>
> raw_spin_lock_irqsave(&devtree_lock, flags);
>
> - __of_free_phandle_cache();
> + shadow = __of_free_phandle_cache();
>
> raw_spin_unlock_irqrestore(&devtree_lock, flags);
> -
> + kfree(shadow);
> return 0;
> }
> #if !defined(CONFIG_MODULES)
> @@ -197,10 +201,12 @@ void of_populate_phandle_cache(void)
> u32 cache_entries;
> struct device_node *np;
> u32 phandles = 0;
> + struct device_node **shadow;
> + struct device_node **tmp_phandle_cache;
>
> raw_spin_lock_irqsave(&devtree_lock, flags);
>
> - __of_free_phandle_cache();
> + shadow = __of_free_phandle_cache();
>
> for_each_of_allnodes(np)
> if (np->phandle && np->phandle != OF_PHANDLE_ILLEGAL)
> @@ -208,12 +214,19 @@ void of_populate_phandle_cache(void)
>
> if (!phandles)
> goto out;
> + /*
> + * kcalloc() can't be used while a raw_spinlock_t held so it is dropped
> + * for the allocation.
> + */
> + raw_spin_unlock_irqrestore(&devtree_lock, flags);
>
> cache_entries = roundup_pow_of_two(phandles);
> phandle_cache_mask = cache_entries - 1;
>
> - phandle_cache = kcalloc(cache_entries, sizeof(*phandle_cache),
> - GFP_ATOMIC);
> + tmp_phandle_cache = kcalloc(cache_entries, sizeof(*phandle_cache),
> + GFP_ATOMIC);
> + raw_spin_lock_irqsave(&devtree_lock, flags);
> + phandle_cache = tmp_phandle_cache;
> if (!phandle_cache)
> goto out;
>
> @@ -225,6 +238,7 @@ void of_populate_phandle_cache(void)
>
> out:
> raw_spin_unlock_irqrestore(&devtree_lock, flags);
> + kfree(shadow);
> }
>
> void __init of_core_init(void)
>
Reviewed-by: Frank Rowand <frank.rowand@sony.com>
Compiled and booted on 5.4. Did not do any more detailed testing.
-Frank
prev parent reply other threads:[~2019-11-30 2:46 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-11-11 17:21 [PATCH] of: allocate / free phandle cache outside of the devtree_lock Sebastian Andrzej Siewior
2019-11-12 3:35 ` Rob Herring
2019-11-12 9:10 ` Sebastian Andrzej Siewior
2019-11-12 15:55 ` Rob Herring
2019-11-12 23:46 ` Frank Rowand
2019-11-13 0:48 ` Rob Herring
2019-11-13 16:52 ` Frank Rowand
2019-11-12 22:48 ` Frank Rowand
2019-11-29 13:57 ` Sebastian Andrzej Siewior
2019-11-30 2:48 ` Frank Rowand
2019-11-29 14:04 ` [PATCH v2] " Sebastian Andrzej Siewior
2019-11-30 2:46 ` Frank Rowand [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=14b65198-fea8-377c-2147-86cb2680bee2@gmail.com \
--to=frowand.list@gmail.com \
--cc=bigeasy@linutronix.de \
--cc=devicetree@vger.kernel.org \
--cc=robh+dt@kernel.org \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.