[PATCH v7 11/15] thermal: devfreq_cooling: work on a copy of device status

From: Lukasz Luba
Date: Mon May 11 2020 - 07:21:37 EST


Devfreq framework can change the device status in the background. To
mitigate this situation make a copy of the status structure and use it
for internal calculations.

Signed-off-by: Lukasz Luba <lukasz.luba@xxxxxxx>
---
drivers/thermal/devfreq_cooling.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/thermal/devfreq_cooling.c b/drivers/thermal/devfreq_cooling.c
index 396f16bb6566..36ec6a48606c 100644
--- a/drivers/thermal/devfreq_cooling.c
+++ b/drivers/thermal/devfreq_cooling.c
@@ -348,14 +348,20 @@ static int devfreq_cooling_power2state(struct thermal_cooling_device *cdev,
{
struct devfreq_cooling_device *dfc = cdev->devdata;
struct devfreq *df = dfc->devfreq;
- struct devfreq_dev_status *status = &df->last_status;
- unsigned long freq = status->current_frequency;
+ struct devfreq_dev_status status;
unsigned long busy_time;
+ unsigned long freq;
s32 dyn_power;
u32 static_power;
s32 est_power;
int i;

+ mutex_lock(&df->lock);
+ status = df->last_status;
+ mutex_unlock(&df->lock);
+
+ freq = status.current_frequency;
+
if (dfc->power_ops->get_real_power) {
/* Scale for resource utilization */
est_power = power * dfc->res_util;
@@ -367,8 +373,8 @@ static int devfreq_cooling_power2state(struct thermal_cooling_device *cdev,
dyn_power = dyn_power > 0 ? dyn_power : 0;

/* Scale dynamic power for utilization */
- busy_time = status->busy_time ?: 1;
- est_power = (dyn_power * status->total_time) / busy_time;
+ busy_time = status.busy_time ?: 1;
+ est_power = (dyn_power * status.total_time) / busy_time;
}

/*
--
2.17.1