]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
thermal: core: Free thermal zone ID later during removal
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 7 Apr 2026 13:58:34 +0000 (15:58 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Wed, 8 Apr 2026 10:30:30 +0000 (12:30 +0200)
The thermal zone removal ordering is different from the thermal zone
registration rollback path ordering and the former is arguably
problematic because freeing a thermal zone ID prematurely may cause
it to be used during the registration of another thermal zone which
may fail as a result.

Prevent that from occurring by changing the thermal zone removal
ordering to reflect the thermal zone registration rollback path
ordering.

Also more the ida_destroy() call from thermal_zone_device_unregister()
to thermal_release() for consistency.

Fixes: b31ef8285b19 ("thermal core: convert ID allocation to IDA")
Cc: All applicable <stable@vger.kernel.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Link: https://patch.msgid.link/5063934.GXAFRqVoOG@rafael.j.wysocki
drivers/thermal/thermal_core.c

index 6e10b2fe29724a9872260edf760d563ab20e3b89..c1ec98591703ab3e634a09b5df73a0721522b29f 100644 (file)
@@ -965,6 +965,7 @@ static void thermal_release(struct device *dev)
                tz = to_thermal_zone(dev);
                thermal_zone_destroy_device_groups(tz);
                thermal_set_governor(tz, NULL);
+               ida_destroy(&tz->ida);
                mutex_destroy(&tz->lock);
                complete(&tz->removal);
        } else if (!strncmp(dev_name(dev), "cooling_device",
@@ -1729,8 +1730,6 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
 
        thermal_thresholds_exit(tz);
        thermal_remove_hwmon_sysfs(tz);
-       ida_free(&thermal_tz_ida, tz->id);
-       ida_destroy(&tz->ida);
 
        device_del(&tz->device);
        put_device(&tz->device);
@@ -1738,6 +1737,9 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
        thermal_notify_tz_delete(tz);
 
        wait_for_completion(&tz->removal);
+
+       ida_free(&thermal_tz_ida, tz->id);
+
        kfree(tz->tzp);
        kfree(tz);
 }