[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20190412183150.102131-2-sboyd@kernel.org>
Date: Fri, 12 Apr 2019 11:31:42 -0700
From: Stephen Boyd <sboyd@...nel.org>
To: Michael Turquette <mturquette@...libre.com>,
Stephen Boyd <sboyd@...nel.org>
Cc: linux-kernel@...r.kernel.org, linux-clk@...r.kernel.org,
Miquel Raynal <miquel.raynal@...tlin.com>,
Jerome Brunet <jbrunet@...libre.com>,
Russell King <linux@...linux.org.uk>,
Jeffrey Hugo <jhugo@...eaurora.org>,
Chen-Yu Tsai <wens@...e.org>,
Matti Vaittinen <matti.vaittinen@...rohmeurope.com>
Subject: [PATCH v4 1/9] clkdev: Hold clocks_mutex while iterating clocks list
We recently introduced a change to support devm clk lookups. That change
introduced a code-path that used clk_find() without holding the
'clocks_mutex'. Unfortunately, clk_find() iterates over the 'clocks'
list and so we need to prevent the list from being modified at the same
time. Do this by holding the mutex and checking to make sure it's held
while iterating the list.
Note, we don't really care if the lookup is freed after we find it with
clk_find() because we're just doing a pointer comparison, but if we did
care we would need to keep holding the mutex while we dereference the
clk_lookup pointer.
Fixes: 3eee6c7d119c ("clkdev: add managed clkdev lookup registration")
Cc: Miquel Raynal <miquel.raynal@...tlin.com>
Cc: Jerome Brunet <jbrunet@...libre.com>
Cc: Russell King <linux@...linux.org.uk>
Cc: Michael Turquette <mturquette@...libre.com>
Cc: Jeffrey Hugo <jhugo@...eaurora.org>
Cc: Chen-Yu Tsai <wens@...e.org>
Cc: Matti Vaittinen <matti.vaittinen@...rohmeurope.com>
Signed-off-by: Stephen Boyd <sboyd@...nel.org>
---
I plan to take this through clk-fixes for v5.1-rc series.
drivers/clk/clkdev.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 8c4435c53f09..6e787cc9e5b9 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -46,6 +46,8 @@ static struct clk_lookup *clk_find(const char *dev_id, const char *con_id)
if (con_id)
best_possible += 1;
+ lockdep_assert_held(&clocks_mutex);
+
list_for_each_entry(p, &clocks, node) {
match = 0;
if (p->dev_id) {
@@ -402,7 +404,10 @@ void devm_clk_release_clkdev(struct device *dev, const char *con_id,
struct clk_lookup *cl;
int rval;
+ mutex_lock(&clocks_mutex);
cl = clk_find(dev_id, con_id);
+ mutex_unlock(&clocks_mutex);
+
WARN_ON(!cl);
rval = devres_release(dev, devm_clkdev_release,
devm_clk_match_clkdev, cl);
--
Sent by a computer through tubes
Powered by blists - more mailing lists