diff options
author | Viresh Kumar <viresh.kumar@linaro.org> | 2023-06-08 13:10:14 +0530 |
---|---|---|
committer | Viresh Kumar <viresh.kumar@linaro.org> | 2023-06-14 09:20:50 +0530 |
commit | 64aaeb708245acdcbe51cf30c84418668c044d80 (patch) | |
tree | bf91e1abacf6b02272cc394a3487cce0b34c280b /drivers | |
parent | 167eb2bd947d9c04b0f6f1a5495ce4a99eeab598 (diff) | |
download | linux-64aaeb708245acdcbe51cf30c84418668c044d80.tar.gz linux-64aaeb708245acdcbe51cf30c84418668c044d80.tar.bz2 linux-64aaeb708245acdcbe51cf30c84418668c044d80.zip |
OPP: Protect `lazy_opp_tables` list with `opp_table_lock`
The `opp_table_lock` lock is already used to protect the list elsewhere,
use it while adding or removing entries from it.
Reported-by: Stephan Gerhold <stephan.gerhold@kernkonzept.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Tested-by: Stephan Gerhold <stephan.gerhold@kernkonzept.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/opp/of.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/drivers/opp/of.c b/drivers/opp/of.c index c740a907ef76..ac2179d5da4c 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c @@ -21,7 +21,7 @@ #include "opp.h" -/* OPP tables with uninitialized required OPPs */ +/* OPP tables with uninitialized required OPPs, protected by opp_table_lock */ static LIST_HEAD(lazy_opp_tables); /* @@ -148,7 +148,10 @@ static void _opp_table_free_required_tables(struct opp_table *opp_table) opp_table->required_opp_count = 0; opp_table->required_opp_tables = NULL; + + mutex_lock(&opp_table_lock); list_del(&opp_table->lazy); + mutex_unlock(&opp_table_lock); } /* @@ -197,8 +200,15 @@ static void _opp_table_alloc_required_tables(struct opp_table *opp_table, } /* Let's do the linking later on */ - if (lazy) + if (lazy) { + /* + * The OPP table is not held while allocating the table, take it + * now to avoid corruption to the lazy_opp_tables list. + */ + mutex_lock(&opp_table_lock); list_add(&opp_table->lazy, &lazy_opp_tables); + mutex_unlock(&opp_table_lock); + } else _update_set_required_opps(opp_table); |