Thermal control fix for 6.11-rc1

Fix a flood of kernel messages coming from the thermal core on systems
 where iwlwifi is loaded, but the network interfaces controlled by it
 are down (Rafael Wysocki).
 -----BEGIN PGP SIGNATURE-----
 
 iQJGBAABCAAwFiEE4fcc61cGeeHD/fCwgsRv/nhiVHEFAmaeXXESHHJqd0Byand5
 c29ja2kubmV0AAoJEILEb/54YlRxsh0P/3vULlwFXtsUv88raGg/T+bfbTeKoDBE
 haJ+wlGnpRXcavFO2gSuG7yXmpKNHUIKiBFu8O7y2eoyC4c76+JX2DZUjx1VrJ0m
 adyWeKvPFGvanfjQtxVqA94Ruog4BZS+rBSqPOlSEQQmPYWULJMnAh4q8iSqHRD7
 r2JeCoDRdYK0KBZ0w8dYeVQYDmGWJ6hd6tjdbwQUC362r1A3faLrL6hftWzd63mp
 v0m0qbUh4ask4Jf0olje8XX+Erlu++bq3wg3CuAcmExU7REqkLAvUoDEtzL8mXp1
 DU8QzT7VEm2oAQ0m54gAvPk4O26BZe9hdpVFvM+CU0BrsqVo2ibIbfCYEp0/+Fes
 JP3mSaLCsJXpin/L4IfwyEMPxbLNM4ueybc4Bs4ZW5kSzJ3wD0GqacQ0HWEEGOCU
 7fYFVvPuVgOoq7d3NePSdxL5mD19tBZTEt24CSyehS+BwsEqrPCUWpjM04WfoPCx
 wg0m6XDat8Vkyc4D2kZY83dJIpdagIDDJyc5t7YimKHh/n+EsC7T5YePDmaOJeJU
 LQDb95awUOVa7OA/JAr0JFPmVMs6sFViF7DTlZ51Ok/sq6Ubhxtvq8eSYOycWo6O
 eoFV9E1dUXAWXQQRUhsUgiJSXc4ZwsBhTve3iV0eL4XY7MzOO1MY9T/DJJkBpmi5
 BC8evRUotuNn
 =JZT5
 -----END PGP SIGNATURE-----

Merge tag 'thermal-6.11-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull thermal control fix from Rafael Wysocki:
 "Fix a flood of kernel messages coming from the thermal core on systems
  where iwlwifi is loaded, but the network interfaces controlled by it
  are down (Rafael Wysocki)"

* tag 'thermal-6.11-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  thermal: core: Allow thermal zones to tell the core to ignore them
This commit is contained in:
Linus Torvalds 2024-07-22 12:13:48 -07:00
commit 539fbb9123
4 changed files with 37 additions and 29 deletions

View File

@ -621,8 +621,14 @@ static int iwl_mvm_tzone_get_temp(struct thermal_zone_device *device,
guard(mvm)(mvm);
if (!iwl_mvm_firmware_running(mvm) ||
mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR)
return -ENODATA;
mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR) {
/*
* Tell the core that there is no valid temperature value to
* return, but it need not worry about this.
*/
*temperature = THERMAL_TEMP_INVALID;
return 0;
}
ret = iwl_mvm_get_temp(mvm, &temp);
if (ret)

View File

@ -300,8 +300,6 @@ static void monitor_thermal_zone(struct thermal_zone_device *tz)
thermal_zone_device_set_polling(tz, tz->passive_delay_jiffies);
else if (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)
@ -382,7 +380,7 @@ static void handle_thermal_trip(struct thermal_zone_device *tz,
td->threshold = trip->temperature;
if (tz->last_temperature >= old_threshold &&
tz->last_temperature != THERMAL_TEMP_INVALID) {
tz->last_temperature != THERMAL_TEMP_INIT) {
/*
* Mitigation is under way, so it needs to stop if the zone
* temperature falls below the low temperature of the trip.
@ -417,27 +415,6 @@ static void handle_thermal_trip(struct thermal_zone_device *tz,
}
}
static void update_temperature(struct thermal_zone_device *tz)
{
int temp, ret;
ret = __thermal_zone_get_temp(tz, &temp);
if (ret) {
if (ret != -EAGAIN)
dev_warn(&tz->device,
"failed to read out thermal zone (%d)\n",
ret);
return;
}
tz->last_temperature = tz->temperature;
tz->temperature = temp;
trace_thermal_temperature(tz);
thermal_genl_sampling_temp(tz->id, temp);
}
static void thermal_zone_device_check(struct work_struct *work)
{
struct thermal_zone_device *tz = container_of(work, struct
@ -452,7 +429,7 @@ static void thermal_zone_device_init(struct thermal_zone_device *tz)
INIT_DELAYED_WORK(&tz->poll_queue, thermal_zone_device_check);
tz->temperature = THERMAL_TEMP_INVALID;
tz->temperature = THERMAL_TEMP_INIT;
tz->passive = 0;
tz->prev_low_trip = -INT_MAX;
tz->prev_high_trip = INT_MAX;
@ -504,6 +481,7 @@ void __thermal_zone_device_update(struct thermal_zone_device *tz,
struct thermal_trip_desc *td;
LIST_HEAD(way_down_list);
LIST_HEAD(way_up_list);
int temp, ret;
if (tz->suspended)
return;
@ -511,10 +489,29 @@ void __thermal_zone_device_update(struct thermal_zone_device *tz,
if (!thermal_zone_device_is_enabled(tz))
return;
update_temperature(tz);
ret = __thermal_zone_get_temp(tz, &temp);
if (ret) {
if (ret != -EAGAIN)
dev_info(&tz->device, "Temperature check failed (%d)\n", ret);
if (tz->temperature == THERMAL_TEMP_INVALID)
thermal_zone_device_set_polling(tz, msecs_to_jiffies(THERMAL_RECHECK_DELAY_MS));
return;
} else if (temp <= THERMAL_TEMP_INVALID) {
/*
* Special case: No valid temperature value is available, but
* the zone owner does not want the core to do anything about
* it. Continue regular zone polling if needed, so that this
* function can be called again, but skip everything else.
*/
goto monitor;
}
tz->last_temperature = tz->temperature;
tz->temperature = temp;
trace_thermal_temperature(tz);
thermal_genl_sampling_temp(tz->id, temp);
tz->notify_event = event;

View File

@ -133,6 +133,9 @@ struct thermal_zone_device {
struct thermal_trip_desc trips[] __counted_by(num_trips);
};
/* Initial thermal zone temperature. */
#define THERMAL_TEMP_INIT INT_MIN
/*
* Default delay after a failing thermal zone temperature check before
* attempting to check it again.

View File

@ -163,6 +163,8 @@ int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp)
}
ret = __thermal_zone_get_temp(tz, temp);
if (!ret && *temp <= THERMAL_TEMP_INVALID)
ret = -ENODATA;
unlock:
mutex_unlock(&tz->lock);