Re: [PATCH 1/3] thermal: cpufreq_cooling: Use a copy of local ops for each cooling device

From: Lukasz Luba
Date: Mon Jun 13 2022 - 07:21:01 EST


Hi Viresh,

Thank you for the ACKs in the other patches and suggestion in this one.

On 6/13/22 10:16, Viresh Kumar wrote:
On 10-06-22, 11:03, Lukasz Luba wrote:
It is very unlikely that one CPU cluster would have the EM and some other
won't have it (because EM registration failed or DT lacks needed entry).
Although, we should avoid modifying global variable with callbacks anyway.
Redesign this and add safety for such situation.

Signed-off-by: Lukasz Luba <lukasz.luba@xxxxxxx>
---
drivers/thermal/cpufreq_cooling.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/thermal/cpufreq_cooling.c b/drivers/thermal/cpufreq_cooling.c
index b8151d95a806..e33183785fac 100644
--- a/drivers/thermal/cpufreq_cooling.c
+++ b/drivers/thermal/cpufreq_cooling.c
@@ -554,7 +554,12 @@ __cpufreq_cooling_register(struct device_node *np,
/* max_level is an index, not a counter */
cpufreq_cdev->max_level = i - 1;
- cooling_ops = &cpufreq_cooling_ops;
+ cooling_ops = kmemdup(&cpufreq_cooling_ops, sizeof(*cooling_ops),
+ GFP_KERNEL);

I don't like the way we are duplicating the ops here. Instead of this it would
be better to add the OPs field in the cooling device structure and fill its
fields from here. The ops structure will be allocated with the cooling device
itself.


I think I know what you mean. Make sense. There are quite a few
different cooling types of devices which are using the API
thermal_of_cooling_device_register() with the custom 'ops'. We
probably don't want to disturb that well working drivers and ecosystem.

Here, I've tried to align this code with the devfreq_cooling, but I
might actually apply your suggestion into the devfreq cooling (so they
will be still aligned). In that case both struct devfreq_cooling_device
and struct cpufreq_cooling_device would get a new field:
struct thermal_cooling_device_ops cooling_ops;
We could then remove the 'global' variables:
devfreq_cooling_ops and cpufreq_cooling_ops from where we copy.
Then we would do the needed assignment to the priv 'cooling_ops' in the
setup code and just use the old API
thermal_of_cooling_device_register() to set the needed 'ops' pointer in
the struct thermal_cooling_device.

Does this sound OK?

Regards,
Lukasz