2020-04-21 20:13:52 +00:00
|
|
|
From 63891871ac6a67c1bae2aa15b3a3aef0f4060b58 Mon Sep 17 00:00:00 2001
|
2018-09-13 17:28:08 +00:00
|
|
|
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
|
|
|
|
Date: Fri, 31 Aug 2018 14:16:30 +0200
|
2020-04-21 20:13:52 +00:00
|
|
|
Subject: [PATCH 021/325] of: allocate / free phandle cache outside of the
|
2019-04-08 23:49:20 +00:00
|
|
|
devtree_lock
|
2020-04-21 20:13:52 +00:00
|
|
|
Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/4.19/older/patches-4.19.115-rt48.tar.xz
|
2018-09-13 17:28:08 +00:00
|
|
|
|
|
|
|
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>
|
|
|
|
---
|
2019-04-08 23:49:20 +00:00
|
|
|
drivers/of/base.c | 19 +++++++++++++------
|
2019-01-14 10:08:29 +00:00
|
|
|
1 file changed, 13 insertions(+), 6 deletions(-)
|
2018-09-13 17:28:08 +00:00
|
|
|
|
2019-04-08 23:49:20 +00:00
|
|
|
diff --git a/drivers/of/base.c b/drivers/of/base.c
|
2020-01-03 23:36:11 +00:00
|
|
|
index f0dbb7ad88cf..c59b30bab0e0 100644
|
2018-09-13 17:28:08 +00:00
|
|
|
--- a/drivers/of/base.c
|
|
|
|
+++ b/drivers/of/base.c
|
2019-01-14 10:08:29 +00:00
|
|
|
@@ -130,31 +130,34 @@ static u32 phandle_cache_mask;
|
|
|
|
/*
|
|
|
|
* Caller must hold devtree_lock.
|
|
|
|
*/
|
|
|
|
-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)
|
|
|
|
@@ -189,10 +192,11 @@ void of_populate_phandle_cache(void)
|
2018-09-13 17:28:08 +00:00
|
|
|
u32 cache_entries;
|
|
|
|
struct device_node *np;
|
|
|
|
u32 phandles = 0;
|
|
|
|
+ struct device_node **shadow;
|
|
|
|
|
|
|
|
raw_spin_lock_irqsave(&devtree_lock, flags);
|
2018-10-30 12:40:05 +00:00
|
|
|
|
2019-01-14 10:08:29 +00:00
|
|
|
- __of_free_phandle_cache();
|
|
|
|
+ shadow = __of_free_phandle_cache();
|
2018-09-13 17:28:08 +00:00
|
|
|
|
|
|
|
for_each_of_allnodes(np)
|
|
|
|
if (np->phandle && np->phandle != OF_PHANDLE_ILLEGAL)
|
2019-01-14 10:08:29 +00:00
|
|
|
@@ -200,12 +204,14 @@ void of_populate_phandle_cache(void)
|
2018-10-30 12:40:05 +00:00
|
|
|
|
2018-09-30 14:00:39 +00:00
|
|
|
if (!phandles)
|
2019-01-14 10:08:29 +00:00
|
|
|
goto out;
|
|
|
|
+ raw_spin_unlock_irqrestore(&devtree_lock, flags);
|
2018-09-30 14:00:39 +00:00
|
|
|
|
2018-09-13 17:28:08 +00:00
|
|
|
cache_entries = roundup_pow_of_two(phandles);
|
|
|
|
phandle_cache_mask = cache_entries - 1;
|
|
|
|
|
2019-01-14 10:08:29 +00:00
|
|
|
phandle_cache = kcalloc(cache_entries, sizeof(*phandle_cache),
|
|
|
|
GFP_ATOMIC);
|
2018-09-13 17:28:08 +00:00
|
|
|
+ raw_spin_lock_irqsave(&devtree_lock, flags);
|
2019-01-14 10:08:29 +00:00
|
|
|
if (!phandle_cache)
|
|
|
|
goto out;
|
2018-09-13 17:28:08 +00:00
|
|
|
|
2019-01-14 10:08:29 +00:00
|
|
|
@@ -217,6 +223,7 @@ void of_populate_phandle_cache(void)
|
2018-09-13 17:28:08 +00:00
|
|
|
|
2019-01-14 10:08:29 +00:00
|
|
|
out:
|
2018-09-13 17:28:08 +00:00
|
|
|
raw_spin_unlock_irqrestore(&devtree_lock, flags);
|
|
|
|
+ kfree(shadow);
|
|
|
|
}
|
2019-01-14 10:08:29 +00:00
|
|
|
|
|
|
|
void __init of_core_init(void)
|
2020-01-03 23:36:11 +00:00
|
|
|
--
|
2020-04-09 19:44:24 +00:00
|
|
|
2.25.1
|
2020-01-03 23:36:11 +00:00
|
|
|
|