Skip to content

Commit

Permalink
clkdev: Hold clocks_mutex while iterating clocks list
Browse files Browse the repository at this point in the history
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: 3eee6c7 ("clkdev: add managed clkdev lookup registration")
Cc: Miquel Raynal <miquel.raynal@bootlin.com>
Cc: Jerome Brunet <jbrunet@baylibre.com>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Michael Turquette <mturquette@baylibre.com>
Cc: Jeffrey Hugo <jhugo@codeaurora.org>
Cc: Chen-Yu Tsai <wens@csie.org>
Cc: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
Acked-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
Tested-by: Jeffrey Hugo <jhugo@codeaurora.org>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
  • Loading branch information
Stephen Boyd committed Apr 18, 2019
1 parent f89b9e1 commit 5a7efda
Showing 1 changed file with 5 additions and 0 deletions.
5 changes: 5 additions & 0 deletions drivers/clk/clkdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 5a7efda

Please sign in to comment.