2023-06-08 07:59:21

by Viresh Kumar

[permalink] [raw]
Subject: [PATCH 1/2] OPP: Staticize `lazy_opp_tables` in of.c

`lazy_opp_tables` is only used in of.c, move it there and mark it
`static`.

Signed-off-by: Viresh Kumar <[email protected]>
---
drivers/opp/core.c | 3 ---
drivers/opp/of.c | 3 +++
drivers/opp/opp.h | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/opp/core.c b/drivers/opp/core.c
index 7046487dc6f4..9f918077cd62 100644
--- a/drivers/opp/core.c
+++ b/drivers/opp/core.c
@@ -29,9 +29,6 @@
*/
LIST_HEAD(opp_tables);

-/* OPP tables with uninitialized required OPPs */
-LIST_HEAD(lazy_opp_tables);
-
/* Lock to allow exclusive modification to the device and opp lists */
DEFINE_MUTEX(opp_table_lock);
/* Flag indicating that opp_tables list is being updated at the moment */
diff --git a/drivers/opp/of.c b/drivers/opp/of.c
index 8246e9b7afe7..c740a907ef76 100644
--- a/drivers/opp/of.c
+++ b/drivers/opp/of.c
@@ -21,6 +21,9 @@

#include "opp.h"

+/* OPP tables with uninitialized required OPPs */
+static LIST_HEAD(lazy_opp_tables);
+
/*
* Returns opp descriptor node for a device node, caller must
* do of_node_put().
diff --git a/drivers/opp/opp.h b/drivers/opp/opp.h
index 2a057c42ddf4..eb71385d96c1 100644
--- a/drivers/opp/opp.h
+++ b/drivers/opp/opp.h
@@ -26,7 +26,7 @@ struct regulator;
/* Lock to allow exclusive modification to the device and opp lists */
extern struct mutex opp_table_lock;

-extern struct list_head opp_tables, lazy_opp_tables;
+extern struct list_head opp_tables;

/* OPP Config flags */
#define OPP_CONFIG_CLK BIT(0)
--
2.31.1.272.g89b43f80a514



2023-06-08 08:12:17

by Viresh Kumar

[permalink] [raw]
Subject: [PATCH 2/2] 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 <[email protected]>
Signed-off-by: Viresh Kumar <[email protected]>
---
Stephan: Can you please give this a try ?

drivers/opp/of.c | 14 ++++++++++++--
1 file 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);

--
2.31.1.272.g89b43f80a514


2023-06-13 13:15:40

by Stephan Gerhold

[permalink] [raw]
Subject: Re: [PATCH 2/2] OPP: Protect `lazy_opp_tables` list with `opp_table_lock`

On Thu, Jun 08, 2023 at 01:13:23PM +0530, Viresh Kumar wrote:
> 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 <[email protected]>
> Signed-off-by: Viresh Kumar <[email protected]>
> ---
> Stephan: Can you please give this a try ?

Thanks, works fine for me. (Note that I don't have any races or
corruption without this patch either so the testing result might
not mean too much.) The patch also looks good!

Tested-by: Stephan Gerhold <[email protected]>

>
> drivers/opp/of.c | 14 ++++++++++++--
> 1 file 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);
>
> --
> 2.31.1.272.g89b43f80a514
>

--
Stephan Gerhold
Kernkonzept GmbH at Dresden, Germany, HRB 31129, CEO Dr.-Ing. Michael Hohmuth