Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

thermal: gov_power_allocator: Update total_weight on bind and cdev updates

params->total_weight is not initialized during bind and not updated when
the bound cdev changes. The cooling device weight will not be used due
to the uninitialized total_weight, until an update via sysfs is
triggered.

The bound cdevs are updated during thermal zone registration, where each
cooling device will be bound to the thermal zone one by one, but
power_allocator_bind() can be called without an additional cdev update
when manually changing the policy of a thermal zone via sysfs.

Add a new function to handle weight update logic, including updating
total_weight, and call it when bind, weight changes, and cdev updates to
ensure total_weight is always correct.

Fixes: a3cd6db4cc2e ("thermal: gov_power_allocator: Support new update callback of weights")
Signed-off-by: Yu-Che Cheng <giver@chromium.org>
Link: https://patch.msgid.link/20250222-fix-power-allocator-weight-v2-1-a94de86b685a@chromium.org
[ rjw: Changelog edits ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

authored by

Yu-Che Cheng and committed by
Rafael J. Wysocki
0cde378a 423de5b5

+22 -8
+22 -8
drivers/thermal/gov_power_allocator.c
··· 641 641 return ret; 642 642 } 643 643 644 + static void power_allocator_update_weight(struct power_allocator_params *params) 645 + { 646 + const struct thermal_trip_desc *td; 647 + struct thermal_instance *instance; 648 + 649 + if (!params->trip_max) 650 + return; 651 + 652 + td = trip_to_trip_desc(params->trip_max); 653 + 654 + params->total_weight = 0; 655 + list_for_each_entry(instance, &td->thermal_instances, trip_node) 656 + if (power_actor_is_valid(instance)) 657 + params->total_weight += instance->weight; 658 + } 659 + 644 660 static void power_allocator_update_tz(struct thermal_zone_device *tz, 645 661 enum thermal_notify_event reason) 646 662 { ··· 672 656 if (power_actor_is_valid(instance)) 673 657 num_actors++; 674 658 675 - if (num_actors == params->num_actors) 676 - return; 659 + if (num_actors != params->num_actors) 660 + allocate_actors_buffer(params, num_actors); 677 661 678 - allocate_actors_buffer(params, num_actors); 679 - break; 662 + fallthrough; 680 663 case THERMAL_INSTANCE_WEIGHT_CHANGED: 681 - params->total_weight = 0; 682 - list_for_each_entry(instance, &td->thermal_instances, trip_node) 683 - if (power_actor_is_valid(instance)) 684 - params->total_weight += instance->weight; 664 + power_allocator_update_weight(params); 685 665 break; 686 666 default: 687 667 break; ··· 742 730 reset_pid_controller(params); 743 731 744 732 tz->governor_data = params; 733 + 734 + power_allocator_update_weight(params); 745 735 746 736 return 0; 747 737