Skip to content

Commit 042a3d8

Browse files
committed
thermal: core: Move passive polling management to the core
Passive polling is enabled by setting the 'passive' field in struct thermal_zone_device to a positive value so long as the 'passive_delay_jiffies' field is greater than zero. It causes the thermal core to actively check the thermal zone temperature periodically which in theory should be done after crossing a passive trip point on the way up in order to allow governors to react more rapidly to temperature changes and adjust mitigation more precisely. However, the 'passive' field in struct thermal_zone_device is currently managed by governors which is quite problematic. First of all, only two governors, Step-Wise and Power Allocator, update that field at all, so the other governors do not benefit from passive polling, although in principle they should. Moreover, if the zone governor is changed from, say, Step-Wise to Fair-Share after 'passive' has been incremented by the former, it is not going to be reset back to zero by the latter even if the zone temperature falls down below all passive trip points. For this reason, make handle_thermal_trip() increment 'passive' to enable passive polling for the given thermal zone whenever a passive trip point is crossed on the way up and decrement it whenever a passive trip point is crossed on the way down. Also remove the 'passive' field updates from governors and additionally clear it in thermal_zone_device_init() to prevent passive polling from being enabled after a system resume just beacuse it was enabled before suspending the system. Signed-off-by: Rafael J. Wysocki <[email protected]> Reviewed-by: Lukasz Luba <[email protected]> Tested-by: Lukasz Luba <[email protected]>
1 parent 202aa0d commit 042a3d8

File tree

3 files changed

+18
-18
lines changed

3 files changed

+18
-18
lines changed

drivers/thermal/gov_power_allocator.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ struct power_actor {
6666
* struct power_allocator_params - parameters for the power allocator governor
6767
* @allocated_tzp: whether we have allocated tzp for this thermal zone and
6868
* it needs to be freed on unbind
69+
* @update_cdevs: whether or not update cdevs on the next run
6970
* @err_integral: accumulated error in the PID controller.
7071
* @prev_err: error in the previous iteration of the PID controller.
7172
* Used to calculate the derivative term.
@@ -84,6 +85,7 @@ struct power_actor {
8485
*/
8586
struct power_allocator_params {
8687
bool allocated_tzp;
88+
bool update_cdevs;
8789
s64 err_integral;
8890
s32 prev_err;
8991
u32 sustainable_power;
@@ -533,7 +535,7 @@ static void reset_pid_controller(struct power_allocator_params *params)
533535
params->prev_err = 0;
534536
}
535537

536-
static void allow_maximum_power(struct thermal_zone_device *tz, bool update)
538+
static void allow_maximum_power(struct thermal_zone_device *tz)
537539
{
538540
struct power_allocator_params *params = tz->governor_data;
539541
struct thermal_cooling_device *cdev;
@@ -555,7 +557,7 @@ static void allow_maximum_power(struct thermal_zone_device *tz, bool update)
555557
*/
556558
cdev->ops->get_requested_power(cdev, &req_power);
557559

558-
if (update)
560+
if (params->update_cdevs)
559561
__thermal_cdev_update(cdev);
560562

561563
mutex_unlock(&cdev->lock);
@@ -752,13 +754,13 @@ static void power_allocator_manage(struct thermal_zone_device *tz)
752754

753755
if (trip && tz->temperature < trip->temperature) {
754756
reset_pid_controller(params);
755-
allow_maximum_power(tz, tz->passive);
756-
tz->passive = 0;
757+
allow_maximum_power(tz);
758+
params->update_cdevs = false;
757759
return;
758760
}
759761

760762
allocate_power(tz, params->trip_max->temperature);
761-
tz->passive = 1;
763+
params->update_cdevs = true;
762764
}
763765

764766
static struct thermal_governor thermal_gov_power_allocator = {

drivers/thermal/gov_step_wise.c

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -93,16 +93,6 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
9393
if (instance->initialized && old_target == instance->target)
9494
continue;
9595

96-
if (trip->type == THERMAL_TRIP_PASSIVE) {
97-
/* If needed, update the status of passive polling. */
98-
if (old_target == THERMAL_NO_TARGET &&
99-
instance->target != THERMAL_NO_TARGET)
100-
tz->passive++;
101-
else if (old_target != THERMAL_NO_TARGET &&
102-
instance->target == THERMAL_NO_TARGET)
103-
tz->passive--;
104-
}
105-
10696
instance->initialized = true;
10797

10898
mutex_lock(&instance->cdev->lock);

drivers/thermal/thermal_core.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ static void monitor_thermal_zone(struct thermal_zone_device *tz)
296296
{
297297
if (tz->mode != THERMAL_DEVICE_ENABLED)
298298
thermal_zone_device_set_polling(tz, 0);
299-
else if (tz->passive)
299+
else if (tz->passive > 0)
300300
thermal_zone_device_set_polling(tz, tz->passive_delay_jiffies);
301301
else if (tz->polling_delay_jiffies)
302302
thermal_zone_device_set_polling(tz, tz->polling_delay_jiffies);
@@ -389,6 +389,11 @@ static void handle_thermal_trip(struct thermal_zone_device *tz,
389389
if (tz->temperature < trip->temperature - trip->hysteresis) {
390390
list_add(&td->notify_list_node, way_down_list);
391391
td->notify_temp = trip->temperature - trip->hysteresis;
392+
393+
if (trip->type == THERMAL_TRIP_PASSIVE) {
394+
tz->passive--;
395+
WARN_ON(tz->passive < 0);
396+
}
392397
} else {
393398
td->threshold -= trip->hysteresis;
394399
}
@@ -402,8 +407,10 @@ static void handle_thermal_trip(struct thermal_zone_device *tz,
402407
td->notify_temp = trip->temperature;
403408
td->threshold -= trip->hysteresis;
404409

405-
if (trip->type == THERMAL_TRIP_CRITICAL ||
406-
trip->type == THERMAL_TRIP_HOT)
410+
if (trip->type == THERMAL_TRIP_PASSIVE)
411+
tz->passive++;
412+
else if (trip->type == THERMAL_TRIP_CRITICAL ||
413+
trip->type == THERMAL_TRIP_HOT)
407414
handle_critical_trips(tz, trip);
408415
}
409416
}
@@ -444,6 +451,7 @@ static void thermal_zone_device_init(struct thermal_zone_device *tz)
444451
INIT_DELAYED_WORK(&tz->poll_queue, thermal_zone_device_check);
445452

446453
tz->temperature = THERMAL_TEMP_INVALID;
454+
tz->passive = 0;
447455
tz->prev_low_trip = -INT_MAX;
448456
tz->prev_high_trip = INT_MAX;
449457
list_for_each_entry(pos, &tz->thermal_instances, tz_node)

0 commit comments

Comments
 (0)