]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
thermal: gov_bang_bang: Use governor_data to reduce overhead
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 13 Aug 2024 14:29:11 +0000 (16:29 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 Aug 2024 15:35:54 +0000 (17:35 +0200)
[ Upstream commit 6e6f58a170ea98e44075b761f2da42a5aec47dfb ]

After running once, the for_each_trip_desc() loop in
bang_bang_manage() is pure needless overhead because it is not going to
make any changes unless a new cooling device has been bound to one of
the trips in the thermal zone or the system is resuming from sleep.

For this reason, make bang_bang_manage() set governor_data for the
thermal zone and check it upfront to decide whether or not it needs to
do anything.

However, governor_data needs to be reset in some cases to let
bang_bang_manage() know that it should walk the trips again, so add an
.update_tz() callback to the governor and make the core additionally
invoke it during system resume.

To avoid affecting the other users of that callback unnecessarily, add
a special notification reason for system resume, THERMAL_TZ_RESUME, and
also pass it to __thermal_zone_device_update() called during system
resume for consistency.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Peter Kästle <peter@piie.net>
Reviewed-by: Zhang Rui <rui.zhang@intel.com>
Cc: 6.10+ <stable@vger.kernel.org> # 6.10+
Link: https://patch.msgid.link/2285575.iZASKD2KPV@rjwysocki.net
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/thermal/gov_bang_bang.c
drivers/thermal/thermal_core.c
include/linux/thermal.h

index bc55e0698bfa8c8eb65de5a9391f79acd0cbdd3b..daed67d19efb818d9ac738df5d25a4c4fbd5eb53 100644 (file)
@@ -86,6 +86,10 @@ static void bang_bang_manage(struct thermal_zone_device *tz)
        const struct thermal_trip_desc *td;
        struct thermal_instance *instance;
 
+       /* If the code below has run already, nothing needs to be done. */
+       if (tz->governor_data)
+               return;
+
        for_each_trip_desc(tz, td) {
                const struct thermal_trip *trip = &td->trip;
 
@@ -107,11 +111,25 @@ static void bang_bang_manage(struct thermal_zone_device *tz)
                                bang_bang_set_instance_target(instance, 0);
                }
        }
+
+       tz->governor_data = (void *)true;
+}
+
+static void bang_bang_update_tz(struct thermal_zone_device *tz,
+                               enum thermal_notify_event reason)
+{
+       /*
+        * Let bang_bang_manage() know that it needs to walk trips after binding
+        * a new cdev and after system resume.
+        */
+       if (reason == THERMAL_TZ_BIND_CDEV || reason == THERMAL_TZ_RESUME)
+               tz->governor_data = NULL;
 }
 
 static struct thermal_governor thermal_gov_bang_bang = {
        .name           = "bang_bang",
        .trip_crossed   = bang_bang_control,
        .manage         = bang_bang_manage,
+       .update_tz      = bang_bang_update_tz,
 };
 THERMAL_GOVERNOR_DECLARE(thermal_gov_bang_bang);
index f2d31bc48f52980da9c6742c9ca811dfafe8b8dd..b8d889ef4fa5e64af07b581b79eb7fc079c10227 100644 (file)
@@ -1715,7 +1715,8 @@ static void thermal_zone_device_resume(struct work_struct *work)
        tz->suspended = false;
 
        thermal_zone_device_init(tz);
-       __thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
+       thermal_governor_update_tz(tz, THERMAL_TZ_RESUME);
+       __thermal_zone_device_update(tz, THERMAL_TZ_RESUME);
 
        complete(&tz->resume);
        tz->resuming = false;
index f1155c0439c4b487c76c5b3c79801e3caf8f45bc..13f88317b81bf52aea3132c10e12d7d155843f00 100644 (file)
@@ -55,6 +55,7 @@ enum thermal_notify_event {
        THERMAL_TZ_BIND_CDEV, /* Cooling dev is bind to the thermal zone */
        THERMAL_TZ_UNBIND_CDEV, /* Cooling dev is unbind from the thermal zone */
        THERMAL_INSTANCE_WEIGHT_CHANGED, /* Thermal instance weight changed */
+       THERMAL_TZ_RESUME, /* Thermal zone is resuming after system sleep */
 };
 
 /**