Skip to content

Commit cd7fa3e

Browse files
committed
Merge tag 'thermal-6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull thermal control updates from Rafael Wysocki: "These are thermal core changes, including the addition of support for temperature thresholds that can be set from user space, fixes related to thermal zone initialization, suspend/resume and exit, locking rework and rearrangement of the code handling thermal zone temperature updates. Specifics: - Add support for thermal thresholds that can be added and removed from user space via netlink along with a related library update (Daniel Lezcano) - Fix thermal zone initialization, suspend/resume and exit synchronization issues (Rafael Wysocki) - Rearrange locking in the thermal core to use guards (Rafael Wysocki) - Make the code handling thermal zone temperature updates use sorted lists of trip points to reduce the number of trip points table walks in the thermal core (Rafael Wysocki) - Fix and clean up the thermal testing facility code (Rafael Wysocki) - Fix a Power Allocator thermal governor issue (ZhengShaobo)" * tag 'thermal-6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (45 commits) thermal: testing: Initialize some variables annoteded with _free() thermal: testing: Use DEFINE_FREE() and __free() to simplify code thermal: testing: Simplify tt_get_tt_zone() thermal: gov_power_allocator: Granted power set to max when nobody request power thermal: core: Relocate thermal zone initialization routine thermal: core: Use trip lists for trip crossing detection thermal: core: Eliminate thermal_zone_trip_down() thermal: core: Relocate functions that update trip points thermal: core: Move some trip processing to thermal_trip_crossed() thermal: core: Pass trip descriptor to thermal_trip_crossed() thermal: core: Rearrange __thermal_zone_device_update() thermal: core: Prepare for moving trips between sorted lists thermal: core: Rename trip list node in struct thermal_trip_desc thermal: core: Build sorted lists instead of sorting them later thermal/lib: Fix memory leak on error in thermal_genl_auto() thermal: thresholds: Fix thermal lock annotation issue tools/thermal/thermal-engine: Take into account the thresholds API tools/lib/thermal: Add the threshold netlink ABI tools/lib/thermal: Make more generic the command encoding function thermal: netlink: Add the commands and the events for the thresholds ...
2 parents ad52c55 + 0104dcd commit cd7fa3e

26 files changed

+1650
-733
lines changed

drivers/thermal/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ CFLAGS_thermal_core.o := -I$(src)
66
obj-$(CONFIG_THERMAL) += thermal_sys.o
77
thermal_sys-y += thermal_core.o thermal_sysfs.o
88
thermal_sys-y += thermal_trip.o thermal_helpers.o
9+
thermal_sys-y += thermal_thresholds.o
910

1011
# netlink interface to manage the thermal framework
1112
thermal_sys-$(CONFIG_THERMAL_NETLINK) += thermal_netlink.o

drivers/thermal/gov_bang_bang.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@ static void bang_bang_set_instance_target(struct thermal_instance *instance,
3030

3131
dev_dbg(&instance->cdev->device, "target=%ld\n", instance->target);
3232

33-
mutex_lock(&instance->cdev->lock);
34-
__thermal_cdev_update(instance->cdev);
35-
mutex_unlock(&instance->cdev->lock);
33+
thermal_cdev_update_nocheck(instance->cdev);
3634
}
3735

3836
/**
@@ -67,6 +65,7 @@ static void bang_bang_control(struct thermal_zone_device *tz,
6765
const struct thermal_trip *trip,
6866
bool crossed_up)
6967
{
68+
const struct thermal_trip_desc *td = trip_to_trip_desc(trip);
7069
struct thermal_instance *instance;
7170

7271
lockdep_assert_held(&tz->lock);
@@ -75,10 +74,8 @@ static void bang_bang_control(struct thermal_zone_device *tz,
7574
thermal_zone_trip_id(tz, trip), trip->temperature,
7675
tz->temperature, trip->hysteresis);
7776

78-
list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
79-
if (instance->trip == trip)
80-
bang_bang_set_instance_target(instance, crossed_up);
81-
}
77+
list_for_each_entry(instance, &td->thermal_instances, trip_node)
78+
bang_bang_set_instance_target(instance, crossed_up);
8279
}
8380

8481
static void bang_bang_manage(struct thermal_zone_device *tz)
@@ -104,8 +101,8 @@ static void bang_bang_manage(struct thermal_zone_device *tz)
104101
* to the thermal zone temperature and the trip point threshold.
105102
*/
106103
turn_on = tz->temperature >= td->threshold;
107-
list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
108-
if (!instance->initialized && instance->trip == trip)
104+
list_for_each_entry(instance, &td->thermal_instances, trip_node) {
105+
if (!instance->initialized)
109106
bang_bang_set_instance_target(instance, turn_on);
110107
}
111108
}

drivers/thermal/gov_fair_share.c

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ static int get_trip_level(struct thermal_zone_device *tz)
4444
/**
4545
* fair_share_throttle - throttles devices associated with the given zone
4646
* @tz: thermal_zone_device
47-
* @trip: trip point
47+
* @td: trip point descriptor
4848
* @trip_level: number of trips crossed by the zone temperature
4949
*
5050
* Throttling Logic: This uses three parameters to calculate the new
@@ -61,29 +61,23 @@ static int get_trip_level(struct thermal_zone_device *tz)
6161
* new_state of cooling device = P3 * P2 * P1
6262
*/
6363
static void fair_share_throttle(struct thermal_zone_device *tz,
64-
const struct thermal_trip *trip,
64+
const struct thermal_trip_desc *td,
6565
int trip_level)
6666
{
6767
struct thermal_instance *instance;
6868
int total_weight = 0;
6969
int nr_instances = 0;
7070

71-
list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
72-
if (instance->trip != trip)
73-
continue;
74-
71+
list_for_each_entry(instance, &td->thermal_instances, trip_node) {
7572
total_weight += instance->weight;
7673
nr_instances++;
7774
}
7875

79-
list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
76+
list_for_each_entry(instance, &td->thermal_instances, trip_node) {
8077
struct thermal_cooling_device *cdev = instance->cdev;
8178
u64 dividend;
8279
u32 divisor;
8380

84-
if (instance->trip != trip)
85-
continue;
86-
8781
dividend = trip_level;
8882
dividend *= cdev->max_state;
8983
divisor = tz->num_trips;
@@ -95,9 +89,7 @@ static void fair_share_throttle(struct thermal_zone_device *tz,
9589
}
9690
instance->target = div_u64(dividend, divisor);
9791

98-
mutex_lock(&cdev->lock);
99-
__thermal_cdev_update(cdev);
100-
mutex_unlock(&cdev->lock);
92+
thermal_cdev_update_nocheck(cdev);
10193
}
10294
}
10395

@@ -116,7 +108,7 @@ static void fair_share_manage(struct thermal_zone_device *tz)
116108
trip->type == THERMAL_TRIP_HOT)
117109
continue;
118110

119-
fair_share_throttle(tz, trip, trip_level);
111+
fair_share_throttle(tz, td, trip_level);
120112
}
121113
}
122114

drivers/thermal/gov_power_allocator.c

Lines changed: 46 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,9 @@ struct power_allocator_params {
9797
struct power_actor *power;
9898
};
9999

100-
static bool power_actor_is_valid(struct power_allocator_params *params,
101-
struct thermal_instance *instance)
100+
static bool power_actor_is_valid(struct thermal_instance *instance)
102101
{
103-
return (instance->trip == params->trip_max &&
104-
cdev_is_power_actor(instance->cdev));
102+
return cdev_is_power_actor(instance->cdev);
105103
}
106104

107105
/**
@@ -118,13 +116,14 @@ static bool power_actor_is_valid(struct power_allocator_params *params,
118116
static u32 estimate_sustainable_power(struct thermal_zone_device *tz)
119117
{
120118
struct power_allocator_params *params = tz->governor_data;
119+
const struct thermal_trip_desc *td = trip_to_trip_desc(params->trip_max);
121120
struct thermal_cooling_device *cdev;
122121
struct thermal_instance *instance;
123122
u32 sustainable_power = 0;
124123
u32 min_power;
125124

126-
list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
127-
if (!power_actor_is_valid(params, instance))
125+
list_for_each_entry(instance, &td->thermal_instances, trip_node) {
126+
if (!power_actor_is_valid(instance))
128127
continue;
129128

130129
cdev = instance->cdev;
@@ -323,9 +322,8 @@ power_actor_set_power(struct thermal_cooling_device *cdev,
323322
return ret;
324323

325324
instance->target = clamp_val(state, instance->lower, instance->upper);
326-
mutex_lock(&cdev->lock);
327-
__thermal_cdev_update(cdev);
328-
mutex_unlock(&cdev->lock);
325+
326+
thermal_cdev_update_nocheck(cdev);
329327

330328
return 0;
331329
}
@@ -356,11 +354,19 @@ static void divvy_up_power(struct power_actor *power, int num_actors,
356354
u32 extra_power = 0;
357355
int i;
358356

359-
/*
360-
* Prevent division by 0 if none of the actors request power.
361-
*/
362-
if (!total_req_power)
363-
total_req_power = 1;
357+
if (!total_req_power) {
358+
/*
359+
* Nobody requested anything, just give everybody
360+
* the maximum power
361+
*/
362+
for (i = 0; i < num_actors; i++) {
363+
struct power_actor *pa = &power[i];
364+
365+
pa->granted_power = pa->max_power;
366+
}
367+
368+
return;
369+
}
364370

365371
for (i = 0; i < num_actors; i++) {
366372
struct power_actor *pa = &power[i];
@@ -400,6 +406,7 @@ static void divvy_up_power(struct power_actor *power, int num_actors,
400406
static void allocate_power(struct thermal_zone_device *tz, int control_temp)
401407
{
402408
struct power_allocator_params *params = tz->governor_data;
409+
const struct thermal_trip_desc *td = trip_to_trip_desc(params->trip_max);
403410
unsigned int num_actors = params->num_actors;
404411
struct power_actor *power = params->power;
405412
struct thermal_cooling_device *cdev;
@@ -417,10 +424,10 @@ static void allocate_power(struct thermal_zone_device *tz, int control_temp)
417424
/* Clean all buffers for new power estimations */
418425
memset(power, 0, params->buffer_size);
419426

420-
list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
427+
list_for_each_entry(instance, &td->thermal_instances, trip_node) {
421428
struct power_actor *pa = &power[i];
422429

423-
if (!power_actor_is_valid(params, instance))
430+
if (!power_actor_is_valid(instance))
424431
continue;
425432

426433
cdev = instance->cdev;
@@ -454,10 +461,10 @@ static void allocate_power(struct thermal_zone_device *tz, int control_temp)
454461
power_range);
455462

456463
i = 0;
457-
list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
464+
list_for_each_entry(instance, &td->thermal_instances, trip_node) {
458465
struct power_actor *pa = &power[i];
459466

460-
if (!power_actor_is_valid(params, instance))
467+
if (!power_actor_is_valid(instance))
461468
continue;
462469

463470
power_actor_set_power(instance->cdev, instance,
@@ -538,29 +545,29 @@ static void reset_pid_controller(struct power_allocator_params *params)
538545
static void allow_maximum_power(struct thermal_zone_device *tz)
539546
{
540547
struct power_allocator_params *params = tz->governor_data;
548+
const struct thermal_trip_desc *td = trip_to_trip_desc(params->trip_max);
541549
struct thermal_cooling_device *cdev;
542550
struct thermal_instance *instance;
543551
u32 req_power;
544552

545-
list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
546-
if (!power_actor_is_valid(params, instance))
553+
list_for_each_entry(instance, &td->thermal_instances, trip_node) {
554+
if (!power_actor_is_valid(instance))
547555
continue;
548556

549557
cdev = instance->cdev;
550558

551559
instance->target = 0;
552-
mutex_lock(&cdev->lock);
553-
/*
554-
* Call for updating the cooling devices local stats and avoid
555-
* periods of dozen of seconds when those have not been
556-
* maintained.
557-
*/
558-
cdev->ops->get_requested_power(cdev, &req_power);
559-
560-
if (params->update_cdevs)
561-
__thermal_cdev_update(cdev);
562-
563-
mutex_unlock(&cdev->lock);
560+
scoped_guard(cooling_dev, cdev) {
561+
/*
562+
* Call for updating the cooling devices local stats and
563+
* avoid periods of dozen of seconds when those have not
564+
* been maintained.
565+
*/
566+
cdev->ops->get_requested_power(cdev, &req_power);
567+
568+
if (params->update_cdevs)
569+
__thermal_cdev_update(cdev);
570+
}
564571
}
565572
}
566573

@@ -581,13 +588,11 @@ static void allow_maximum_power(struct thermal_zone_device *tz)
581588
static int check_power_actors(struct thermal_zone_device *tz,
582589
struct power_allocator_params *params)
583590
{
591+
const struct thermal_trip_desc *td = trip_to_trip_desc(params->trip_max);
584592
struct thermal_instance *instance;
585593
int ret = 0;
586594

587-
list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
588-
if (instance->trip != params->trip_max)
589-
continue;
590-
595+
list_for_each_entry(instance, &td->thermal_instances, trip_node) {
591596
if (!cdev_is_power_actor(instance->cdev)) {
592597
dev_warn(&tz->device, "power_allocator: %s is not a power actor\n",
593598
instance->cdev->type);
@@ -635,14 +640,15 @@ static void power_allocator_update_tz(struct thermal_zone_device *tz,
635640
enum thermal_notify_event reason)
636641
{
637642
struct power_allocator_params *params = tz->governor_data;
643+
const struct thermal_trip_desc *td = trip_to_trip_desc(params->trip_max);
638644
struct thermal_instance *instance;
639645
int num_actors = 0;
640646

641647
switch (reason) {
642648
case THERMAL_TZ_BIND_CDEV:
643649
case THERMAL_TZ_UNBIND_CDEV:
644-
list_for_each_entry(instance, &tz->thermal_instances, tz_node)
645-
if (power_actor_is_valid(params, instance))
650+
list_for_each_entry(instance, &td->thermal_instances, trip_node)
651+
if (power_actor_is_valid(instance))
646652
num_actors++;
647653

648654
if (num_actors == params->num_actors)
@@ -652,8 +658,8 @@ static void power_allocator_update_tz(struct thermal_zone_device *tz,
652658
break;
653659
case THERMAL_INSTANCE_WEIGHT_CHANGED:
654660
params->total_weight = 0;
655-
list_for_each_entry(instance, &tz->thermal_instances, tz_node)
656-
if (power_actor_is_valid(params, instance))
661+
list_for_each_entry(instance, &td->thermal_instances, trip_node)
662+
if (power_actor_is_valid(instance))
657663
params->total_weight += instance->weight;
658664
break;
659665
default:

drivers/thermal/gov_step_wise.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,10 @@ static unsigned long get_target_state(struct thermal_instance *instance,
6666
}
6767

6868
static void thermal_zone_trip_update(struct thermal_zone_device *tz,
69-
const struct thermal_trip *trip,
69+
const struct thermal_trip_desc *td,
7070
int trip_threshold)
7171
{
72+
const struct thermal_trip *trip = &td->trip;
7273
enum thermal_trend trend = get_tz_trend(tz, trip);
7374
int trip_id = thermal_zone_trip_id(tz, trip);
7475
struct thermal_instance *instance;
@@ -82,12 +83,9 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
8283
dev_dbg(&tz->device, "Trip%d[type=%d,temp=%d]:trend=%d,throttle=%d\n",
8384
trip_id, trip->type, trip_threshold, trend, throttle);
8485

85-
list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
86+
list_for_each_entry(instance, &td->thermal_instances, trip_node) {
8687
int old_target;
8788

88-
if (instance->trip != trip)
89-
continue;
90-
9189
old_target = instance->target;
9290
instance->target = get_target_state(instance, trend, throttle);
9391

@@ -99,9 +97,9 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
9997

10098
instance->initialized = true;
10199

102-
mutex_lock(&instance->cdev->lock);
103-
instance->cdev->updated = false; /* cdev needs update */
104-
mutex_unlock(&instance->cdev->lock);
100+
scoped_guard(cooling_dev, instance->cdev) {
101+
instance->cdev->updated = false; /* cdev needs update */
102+
}
105103
}
106104
}
107105

@@ -127,11 +125,13 @@ static void step_wise_manage(struct thermal_zone_device *tz)
127125
trip->type == THERMAL_TRIP_HOT)
128126
continue;
129127

130-
thermal_zone_trip_update(tz, trip, td->threshold);
128+
thermal_zone_trip_update(tz, td, td->threshold);
131129
}
132130

133-
list_for_each_entry(instance, &tz->thermal_instances, tz_node)
134-
thermal_cdev_update(instance->cdev);
131+
for_each_trip_desc(tz, td) {
132+
list_for_each_entry(instance, &td->thermal_instances, trip_node)
133+
thermal_cdev_update(instance->cdev);
134+
}
135135
}
136136

137137
static struct thermal_governor thermal_gov_step_wise = {

0 commit comments

Comments
 (0)