@@ -87,6 +87,7 @@ static int devfreq_cooling_set_cur_state(struct thermal_cooling_device *cdev,
87
87
struct devfreq_cooling_device * dfc = cdev -> devdata ;
88
88
struct devfreq * df = dfc -> devfreq ;
89
89
struct device * dev = df -> dev .parent ;
90
+ struct em_perf_state * table ;
90
91
unsigned long freq ;
91
92
int perf_idx ;
92
93
@@ -100,7 +101,11 @@ static int devfreq_cooling_set_cur_state(struct thermal_cooling_device *cdev,
100
101
101
102
if (dfc -> em_pd ) {
102
103
perf_idx = dfc -> max_state - state ;
103
- freq = dfc -> em_pd -> table [perf_idx ].frequency * 1000 ;
104
+
105
+ rcu_read_lock ();
106
+ table = em_perf_state_from_pd (dfc -> em_pd );
107
+ freq = table [perf_idx ].frequency * 1000 ;
108
+ rcu_read_unlock ();
104
109
} else {
105
110
freq = dfc -> freq_table [state ];
106
111
}
@@ -123,14 +128,21 @@ static int devfreq_cooling_set_cur_state(struct thermal_cooling_device *cdev,
123
128
*/
124
129
static int get_perf_idx (struct em_perf_domain * em_pd , unsigned long freq )
125
130
{
126
- int i ;
131
+ struct em_perf_state * table ;
132
+ int i , idx = - EINVAL ;
127
133
134
+ rcu_read_lock ();
135
+ table = em_perf_state_from_pd (em_pd );
128
136
for (i = 0 ; i < em_pd -> nr_perf_states ; i ++ ) {
129
- if (em_pd -> table [i ].frequency == freq )
130
- return i ;
137
+ if (table [i ].frequency != freq )
138
+ continue ;
139
+
140
+ idx = i ;
141
+ break ;
131
142
}
143
+ rcu_read_unlock ();
132
144
133
- return - EINVAL ;
145
+ return idx ;
134
146
}
135
147
136
148
static unsigned long get_voltage (struct devfreq * df , unsigned long freq )
@@ -181,6 +193,7 @@ static int devfreq_cooling_get_requested_power(struct thermal_cooling_device *cd
181
193
struct devfreq_cooling_device * dfc = cdev -> devdata ;
182
194
struct devfreq * df = dfc -> devfreq ;
183
195
struct devfreq_dev_status status ;
196
+ struct em_perf_state * table ;
184
197
unsigned long state ;
185
198
unsigned long freq ;
186
199
unsigned long voltage ;
@@ -204,7 +217,11 @@ static int devfreq_cooling_get_requested_power(struct thermal_cooling_device *cd
204
217
state = dfc -> capped_state ;
205
218
206
219
/* Convert EM power into milli-Watts first */
207
- dfc -> res_util = dfc -> em_pd -> table [state ].power ;
220
+ rcu_read_lock ();
221
+ table = em_perf_state_from_pd (dfc -> em_pd );
222
+ dfc -> res_util = table [state ].power ;
223
+ rcu_read_unlock ();
224
+
208
225
dfc -> res_util /= MICROWATT_PER_MILLIWATT ;
209
226
210
227
dfc -> res_util *= SCALE_ERROR_MITIGATION ;
@@ -225,7 +242,11 @@ static int devfreq_cooling_get_requested_power(struct thermal_cooling_device *cd
225
242
_normalize_load (& status );
226
243
227
244
/* Convert EM power into milli-Watts first */
228
- * power = dfc -> em_pd -> table [perf_idx ].power ;
245
+ rcu_read_lock ();
246
+ table = em_perf_state_from_pd (dfc -> em_pd );
247
+ * power = table [perf_idx ].power ;
248
+ rcu_read_unlock ();
249
+
229
250
* power /= MICROWATT_PER_MILLIWATT ;
230
251
/* Scale power for utilization */
231
252
* power *= status .busy_time ;
@@ -245,13 +266,19 @@ static int devfreq_cooling_state2power(struct thermal_cooling_device *cdev,
245
266
unsigned long state , u32 * power )
246
267
{
247
268
struct devfreq_cooling_device * dfc = cdev -> devdata ;
269
+ struct em_perf_state * table ;
248
270
int perf_idx ;
249
271
250
272
if (state > dfc -> max_state )
251
273
return - EINVAL ;
252
274
253
275
perf_idx = dfc -> max_state - state ;
254
- * power = dfc -> em_pd -> table [perf_idx ].power ;
276
+
277
+ rcu_read_lock ();
278
+ table = em_perf_state_from_pd (dfc -> em_pd );
279
+ * power = table [perf_idx ].power ;
280
+ rcu_read_unlock ();
281
+
255
282
* power /= MICROWATT_PER_MILLIWATT ;
256
283
257
284
return 0 ;
@@ -264,6 +291,7 @@ static int devfreq_cooling_power2state(struct thermal_cooling_device *cdev,
264
291
struct devfreq * df = dfc -> devfreq ;
265
292
struct devfreq_dev_status status ;
266
293
unsigned long freq , em_power_mw ;
294
+ struct em_perf_state * table ;
267
295
s32 est_power ;
268
296
int i ;
269
297
@@ -288,13 +316,16 @@ static int devfreq_cooling_power2state(struct thermal_cooling_device *cdev,
288
316
* Find the first cooling state that is within the power
289
317
* budget. The EM power table is sorted ascending.
290
318
*/
319
+ rcu_read_lock ();
320
+ table = em_perf_state_from_pd (dfc -> em_pd );
291
321
for (i = dfc -> max_state ; i > 0 ; i -- ) {
292
322
/* Convert EM power to milli-Watts to make safe comparison */
293
- em_power_mw = dfc -> em_pd -> table [i ].power ;
323
+ em_power_mw = table [i ].power ;
294
324
em_power_mw /= MICROWATT_PER_MILLIWATT ;
295
325
if (est_power >= em_power_mw )
296
326
break ;
297
327
}
328
+ rcu_read_unlock ();
298
329
299
330
* state = dfc -> max_state - i ;
300
331
dfc -> capped_state = * state ;
0 commit comments