Commit d045c46c authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'thermal-6.10-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull thermal control fixes from Rafael Wysocki:
 "These fix a possible NULL pointer dereference in a thermal governor,
  fix up the handling of thermal zones enabled before their temperature
  can be determined and fix list sorting during thermal zone temperature
  updates.

  Specifics:

   - Prevent the Power Allocator thermal governor from dereferencing a
     NULL pointer if it is bound to a tripless thermal zone (Nícolas
     Prado)

   - Prevent thermal zones enabled too early from staying effectively
     dormant forever because their temperature cannot be determined
     initially (Rafael Wysocki)

   - Fix list sorting during thermal zone temperature updates to ensure
     the proper ordering of trip crossing notifications (Rafael
     Wysocki)"

* tag 'thermal-6.10-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  thermal: core: Fix list sorting in __thermal_zone_device_update()
  thermal: core: Call monitor_thermal_zone() if zone temperature is invalid
  thermal: gov_power_allocator: Return early in manage if trip_max is NULL
parents 367cbaad 94eacc1c
...@@ -759,6 +759,9 @@ static void power_allocator_manage(struct thermal_zone_device *tz) ...@@ -759,6 +759,9 @@ static void power_allocator_manage(struct thermal_zone_device *tz)
return; return;
} }
if (!params->trip_max)
return;
allocate_power(tz, params->trip_max->temperature); allocate_power(tz, params->trip_max->temperature);
params->update_cdevs = true; params->update_cdevs = true;
} }
......
...@@ -300,6 +300,8 @@ static void monitor_thermal_zone(struct thermal_zone_device *tz) ...@@ -300,6 +300,8 @@ static void monitor_thermal_zone(struct thermal_zone_device *tz)
thermal_zone_device_set_polling(tz, tz->passive_delay_jiffies); thermal_zone_device_set_polling(tz, tz->passive_delay_jiffies);
else if (tz->polling_delay_jiffies) else if (tz->polling_delay_jiffies)
thermal_zone_device_set_polling(tz, tz->polling_delay_jiffies); thermal_zone_device_set_polling(tz, tz->polling_delay_jiffies);
else if (tz->temperature == THERMAL_TEMP_INVALID)
thermal_zone_device_set_polling(tz, msecs_to_jiffies(THERMAL_RECHECK_DELAY_MS));
} }
static struct thermal_governor *thermal_get_tz_governor(struct thermal_zone_device *tz) static struct thermal_governor *thermal_get_tz_governor(struct thermal_zone_device *tz)
...@@ -482,16 +484,14 @@ static void thermal_trip_crossed(struct thermal_zone_device *tz, ...@@ -482,16 +484,14 @@ static void thermal_trip_crossed(struct thermal_zone_device *tz,
thermal_governor_trip_crossed(governor, tz, trip, crossed_up); thermal_governor_trip_crossed(governor, tz, trip, crossed_up);
} }
static int thermal_trip_notify_cmp(void *ascending, const struct list_head *a, static int thermal_trip_notify_cmp(void *not_used, const struct list_head *a,
const struct list_head *b) const struct list_head *b)
{ {
struct thermal_trip_desc *tda = container_of(a, struct thermal_trip_desc, struct thermal_trip_desc *tda = container_of(a, struct thermal_trip_desc,
notify_list_node); notify_list_node);
struct thermal_trip_desc *tdb = container_of(b, struct thermal_trip_desc, struct thermal_trip_desc *tdb = container_of(b, struct thermal_trip_desc,
notify_list_node); notify_list_node);
int ret = tdb->notify_temp - tda->notify_temp; return tda->notify_temp - tdb->notify_temp;
return ascending ? ret : -ret;
} }
void __thermal_zone_device_update(struct thermal_zone_device *tz, void __thermal_zone_device_update(struct thermal_zone_device *tz,
...@@ -511,7 +511,7 @@ void __thermal_zone_device_update(struct thermal_zone_device *tz, ...@@ -511,7 +511,7 @@ void __thermal_zone_device_update(struct thermal_zone_device *tz,
update_temperature(tz); update_temperature(tz);
if (tz->temperature == THERMAL_TEMP_INVALID) if (tz->temperature == THERMAL_TEMP_INVALID)
return; goto monitor;
__thermal_zone_set_trips(tz); __thermal_zone_set_trips(tz);
...@@ -520,12 +520,12 @@ void __thermal_zone_device_update(struct thermal_zone_device *tz, ...@@ -520,12 +520,12 @@ void __thermal_zone_device_update(struct thermal_zone_device *tz,
for_each_trip_desc(tz, td) for_each_trip_desc(tz, td)
handle_thermal_trip(tz, td, &way_up_list, &way_down_list); handle_thermal_trip(tz, td, &way_up_list, &way_down_list);
list_sort(&way_up_list, &way_up_list, thermal_trip_notify_cmp); list_sort(NULL, &way_up_list, thermal_trip_notify_cmp);
list_for_each_entry(td, &way_up_list, notify_list_node) list_for_each_entry(td, &way_up_list, notify_list_node)
thermal_trip_crossed(tz, &td->trip, governor, true); thermal_trip_crossed(tz, &td->trip, governor, true);
list_sort(NULL, &way_down_list, thermal_trip_notify_cmp); list_sort(NULL, &way_down_list, thermal_trip_notify_cmp);
list_for_each_entry(td, &way_down_list, notify_list_node) list_for_each_entry_reverse(td, &way_down_list, notify_list_node)
thermal_trip_crossed(tz, &td->trip, governor, false); thermal_trip_crossed(tz, &td->trip, governor, false);
if (governor->manage) if (governor->manage)
...@@ -533,6 +533,7 @@ void __thermal_zone_device_update(struct thermal_zone_device *tz, ...@@ -533,6 +533,7 @@ void __thermal_zone_device_update(struct thermal_zone_device *tz,
thermal_debug_update_trip_stats(tz); thermal_debug_update_trip_stats(tz);
monitor:
monitor_thermal_zone(tz); monitor_thermal_zone(tz);
} }
......
...@@ -133,6 +133,12 @@ struct thermal_zone_device { ...@@ -133,6 +133,12 @@ struct thermal_zone_device {
struct thermal_trip_desc trips[] __counted_by(num_trips); struct thermal_trip_desc trips[] __counted_by(num_trips);
}; };
/*
* Default delay after a failing thermal zone temperature check before
* attempting to check it again.
*/
#define THERMAL_RECHECK_DELAY_MS 250
/* Default Thermal Governor */ /* Default Thermal Governor */
#if defined(CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE) #if defined(CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE)
#define DEFAULT_THERMAL_GOVERNOR "step_wise" #define DEFAULT_THERMAL_GOVERNOR "step_wise"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment