OPP: Protect `lazy_opp_tables` list with `opp_table_lock`
authorViresh Kumar <viresh.kumar@linaro.org>
Thu, 8 Jun 2023 07:40:14 +0000 (13:10 +0530)
committerViresh Kumar <viresh.kumar@linaro.org>
Wed, 14 Jun 2023 03:50:50 +0000 (09:20 +0530)
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>
drivers/opp/of.c

index c740a90..ac2179d 100644 (file)
@@ -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);