History

Merge branch 'thermal-acpi'

Merge a fix for a recent thermal-related regression in the ACPI processor driver. * thermal-acpi: ACPI: processor: thermal: Update CPU cooling devices on cpufreq policy changes thermal: core: Introduce thermal_cooling_device_update() thermal: core: Introduce thermal_cooling_device_present() ACPI: processor: Reorder acpi_processor_driver_init()

Rafael J. Wysocki committed 3 years ago

Commit 6babf382 parents f1b80a3 22c52fa6 files · +182 −25Browse files

Unified · Split

6 files
  1. drivers/acpi/processor_driver.c +6 −6
  2. drivers/acpi/processor_thermal.c +11 −3
  3. drivers/thermal/thermal_core.c +97 −7
  4. drivers/thermal/thermal_core.h +2 −0
  5. drivers/thermal/thermal_sysfs.c +65 −9
  6. include/linux/thermal.h +1 −0
drivers/acpi/processor_driver.c+6−6
@@ -263,6 +263,12 @@ static int __init acpi_processor_driver_init(void) · 262 unmodified lines
263263 if (acpi_disabled)
264264 return 0;
265265
266+ if (!cpufreq_register_notifier(&acpi_processor_notifier_block,
267+ CPUFREQ_POLICY_NOTIFIER)) {
268+ acpi_processor_cpufreq_init = true;
269+ acpi_processor_ignore_ppc_init();
270+ }
271+
266272 result = driver_register(&acpi_processor_driver);
267273 if (result < 0)
268274 return result;
@@ -276,12 +282,6 @@ static int __init acpi_processor_driver_init(void) · 7 unmodified lines
276282 cpuhp_setup_state_nocalls(CPUHP_ACPI_CPUDRV_DEAD, "acpi/cpu-drv:dead",
277283 NULL, acpi_soft_cpu_dead);
278284
279− if (!cpufreq_register_notifier(&acpi_processor_notifier_block,
280− CPUFREQ_POLICY_NOTIFIER)) {
281− acpi_processor_cpufreq_init = true;
282− acpi_processor_ignore_ppc_init();
283− }
284−
285285 acpi_processor_throttling_init();
286286 return 0;
287287 err:
drivers/acpi/processor_thermal.c+11−3
@@ -140,9 +140,13 @@ void acpi_thermal_cpufreq_init(struct cpufreq_policy *policy) · 139 unmodified lines
140140 ret = freq_qos_add_request(&policy->constraints,
141141 &pr->thermal_req,
142142 FREQ_QOS_MAX, INT_MAX);
143− if (ret < 0)
143+ if (ret < 0) {
144144 pr_err("Failed to add freq constraint for CPU%d (%d)\n",
145145 cpu, ret);
146+ continue;
147+ }
148+
149+ thermal_cooling_device_update(pr->cdev);
146150 }
147151 }
148152
@@ -153,8 +157,12 @@ void acpi_thermal_cpufreq_exit(struct cpufreq_policy *policy) · 4 unmodified lines
153157 for_each_cpu(cpu, policy->related_cpus) {
154158 struct acpi_processor *pr = per_cpu(processors, cpu);
155159
156− if (pr)
157− freq_qos_remove_request(&pr->thermal_req);
160+ if (!pr)
161+ continue;
162+
163+ freq_qos_remove_request(&pr->thermal_req);
164+
165+ thermal_cooling_device_update(pr->cdev);
158166 }
159167 }
160168 #else /* ! CONFIG_CPU_FREQ */
drivers/thermal/thermal_core.c+97−7
@@ -613,6 +613,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz, · 612 unmodified lines
613613 struct thermal_instance *pos;
614614 struct thermal_zone_device *pos1;
615615 struct thermal_cooling_device *pos2;
616+ bool upper_no_limit;
616617 int result;
617618
618619 if (trip >= tz->num_trips || trip < 0)
@@ -632,7 +633,13 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz, · 13 unmodified lines
632633
633634 /* lower default 0, upper default max_state */
634635 lower = lower == THERMAL_NO_LIMIT ? 0 : lower;
635− upper = upper == THERMAL_NO_LIMIT ? cdev->max_state : upper;
636+
637+ if (upper == THERMAL_NO_LIMIT) {
638+ upper = cdev->max_state;
639+ upper_no_limit = true;
640+ } else {
641+ upper_no_limit = false;
642+ }
636643
637644 if (lower > upper || upper > cdev->max_state)
638645 return -EINVAL;
@@ -644,6 +651,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz, · 5 unmodified lines
644651 dev->cdev = cdev;
645652 dev->trip = trip;
646653 dev->upper = upper;
654+ dev->upper_no_limit = upper_no_limit;
647655 dev->lower = lower;
648656 dev->target = THERMAL_NO_TARGET;
649657 dev->weight = weight;
@@ -1045,6 +1053,91 @@ devm_thermal_of_cooling_device_register(struct device *dev, · 395 unmodified lines
10451053 }
10461054 EXPORT_SYMBOL_GPL(devm_thermal_of_cooling_device_register);
10471055
1056+static bool thermal_cooling_device_present(struct thermal_cooling_device *cdev)
1057+{
1058+ struct thermal_cooling_device *pos = NULL;
1059+
1060+ list_for_each_entry(pos, &thermal_cdev_list, node) {
1061+ if (pos == cdev)
1062+ return true;
1063+ }
1064+
1065+ return false;
1066+}
1067+
1068+/**
1069+ * thermal_cooling_device_update - Update a cooling device object
1070+ * @cdev: Target cooling device.
1071+ *
1072+ * Update @cdev to reflect a change of the underlying hardware or platform.
1073+ *
1074+ * Must be called when the maximum cooling state of @cdev becomes invalid and so
1075+ * its .get_max_state() callback needs to be run to produce the new maximum
1076+ * cooling state value.
1077+ */
1078+void thermal_cooling_device_update(struct thermal_cooling_device *cdev)
1079+{
1080+ struct thermal_instance *ti;
1081+ unsigned long state;
1082+
1083+ if (IS_ERR_OR_NULL(cdev))
1084+ return;
1085+
1086+ /*
1087+ * Hold thermal_list_lock throughout the update to prevent the device
1088+ * from going away while being updated.
1089+ */
1090+ mutex_lock(&thermal_list_lock);
1091+
1092+ if (!thermal_cooling_device_present(cdev))
1093+ goto unlock_list;
1094+
1095+ /*
1096+ * Update under the cdev lock to prevent the state from being set beyond
1097+ * the new limit concurrently.
1098+ */
1099+ mutex_lock(&cdev->lock);
1100+
1101+ if (cdev->ops->get_max_state(cdev, &cdev->max_state))
1102+ goto unlock;
1103+
1104+ thermal_cooling_device_stats_reinit(cdev);
1105+
1106+ list_for_each_entry(ti, &cdev->thermal_instances, cdev_node) {
1107+ if (ti->upper == cdev->max_state)
1108+ continue;
1109+
1110+ if (ti->upper < cdev->max_state) {
1111+ if (ti->upper_no_limit)
1112+ ti->upper = cdev->max_state;
1113+
1114+ continue;
1115+ }
1116+
1117+ ti->upper = cdev->max_state;
1118+ if (ti->lower > ti->upper)
1119+ ti->lower = ti->upper;
1120+
1121+ if (ti->target == THERMAL_NO_TARGET)
1122+ continue;
1123+
1124+ if (ti->target > ti->upper)
1125+ ti->target = ti->upper;
1126+ }
1127+
1128+ if (cdev->ops->get_cur_state(cdev, &state) || state > cdev->max_state)
1129+ goto unlock;
1130+
1131+ thermal_cooling_device_stats_update(cdev, state);
1132+
1133+unlock:
1134+ mutex_unlock(&cdev->lock);
1135+
1136+unlock_list:
1137+ mutex_unlock(&thermal_list_lock);
1138+}
1139+EXPORT_SYMBOL_GPL(thermal_cooling_device_update);
1140+
10481141 static void __unbind(struct thermal_zone_device *tz, int mask,
10491142 struct thermal_cooling_device *cdev)
10501143 {
@@ -1067,20 +1160,17 @@ void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev) · 16 unmodified lines
10671160 int i;
10681161 const struct thermal_zone_params *tzp;
10691162 struct thermal_zone_device *tz;
1070− struct thermal_cooling_device *pos = NULL;
10711163
10721164 if (!cdev)
10731165 return;
10741166
10751167 mutex_lock(&thermal_list_lock);
1076− list_for_each_entry(pos, &thermal_cdev_list, node)
1077− if (pos == cdev)
1078− break;
1079− if (pos != cdev) {
1080− /* thermal cooling device not found */
1168+
1169+ if (!thermal_cooling_device_present(cdev)) {
10811170 mutex_unlock(&thermal_list_lock);
10821171 return;
10831172 }
1173+
10841174 list_del(&cdev->node);
10851175
10861176 /* Unbind all thermal zones associated with 'this' cdev */
drivers/thermal/thermal_core.h+2−0
@@ -101,6 +101,7 @@ struct thermal_instance { · 100 unmodified lines
101101 struct list_head tz_node; /* node in tz->thermal_instances */
102102 struct list_head cdev_node; /* node in cdev->thermal_instances */
103103 unsigned int weight; /* The weight of the cooling device */
104+ bool upper_no_limit;
104105 };
105106
106107 #define to_thermal_zone(_dev) \
@@ -127,6 +128,7 @@ int thermal_zone_create_device_groups(struct thermal_zone_device *, int); · 20 unmodified lines
127128 void thermal_zone_destroy_device_groups(struct thermal_zone_device *);
128129 void thermal_cooling_device_setup_sysfs(struct thermal_cooling_device *);
129130 void thermal_cooling_device_destroy_sysfs(struct thermal_cooling_device *cdev);
131+void thermal_cooling_device_stats_reinit(struct thermal_cooling_device *cdev);
130132 /* used only at binding time */
131133 ssize_t trip_point_show(struct device *, struct device_attribute *, char *);
132134 ssize_t weight_show(struct device *, struct device_attribute *, char *);
drivers/thermal/thermal_sysfs.c+65−9
@@ -685,6 +685,8 @@ void thermal_cooling_device_stats_update(struct thermal_cooling_device *cdev, · 684 unmodified lines
685685 {
686686 struct cooling_dev_stats *stats = cdev->stats;
687687
688+ lockdep_assert_held(&cdev->lock);
689+
688690 if (!stats)
689691 return;
690692
@@ -706,13 +708,22 @@ static ssize_t total_trans_show(struct device *dev, · 15 unmodified lines
706708 struct device_attribute *attr, char *buf)
707709 {
708710 struct thermal_cooling_device *cdev = to_cooling_device(dev);
709− struct cooling_dev_stats *stats = cdev->stats;
710− int ret;
711+ struct cooling_dev_stats *stats;
712+ int ret = 0;
713+
714+ mutex_lock(&cdev->lock);
715+
716+ stats = cdev->stats;
717+ if (!stats)
718+ goto unlock;
711719
712720 spin_lock(&stats->lock);
713721 ret = sprintf(buf, "%u\n", stats->total_trans);
714722 spin_unlock(&stats->lock);
715723
724+unlock:
725+ mutex_unlock(&cdev->lock);
726+
716727 return ret;
717728 }
718729
@@ -721,11 +732,18 @@ time_in_state_ms_show(struct device *dev, struct device_attribute *attr, · 2 unmodified lines
721732 char *buf)
722733 {
723734 struct thermal_cooling_device *cdev = to_cooling_device(dev);
724− struct cooling_dev_stats *stats = cdev->stats;
735+ struct cooling_dev_stats *stats;
725736 ssize_t len = 0;
726737 int i;
727738
739+ mutex_lock(&cdev->lock);
740+
741+ stats = cdev->stats;
742+ if (!stats)
743+ goto unlock;
744+
728745 spin_lock(&stats->lock);
746+
729747 update_time_in_state(stats);
730748
731749 for (i = 0; i <= cdev->max_state; i++) {
@@ -734,6 +752,9 @@ time_in_state_ms_show(struct device *dev, struct device_attribute *attr, · 2 unmodified lines
734752 }
735753 spin_unlock(&stats->lock);
736754
755+unlock:
756+ mutex_unlock(&cdev->lock);
757+
737758 return len;
738759 }
739760
@@ -742,8 +763,16 @@ reset_store(struct device *dev, struct device_attribute *attr, const char *buf, · 2 unmodified lines
742763 size_t count)
743764 {
744765 struct thermal_cooling_device *cdev = to_cooling_device(dev);
745− struct cooling_dev_stats *stats = cdev->stats;
746− int i, states = cdev->max_state + 1;
766+ struct cooling_dev_stats *stats;
767+ int i, states;
768+
769+ mutex_lock(&cdev->lock);
770+
771+ stats = cdev->stats;
772+ if (!stats)
773+ goto unlock;
774+
775+ states = cdev->max_state + 1;
747776
748777 spin_lock(&stats->lock);
749778
@@ -757,6 +786,9 @@ reset_store(struct device *dev, struct device_attribute *attr, const char *buf, · 7 unmodified lines
757786
758787 spin_unlock(&stats->lock);
759788
789+unlock:
790+ mutex_unlock(&cdev->lock);
791+
760792 return count;
761793 }
762794
@@ -764,10 +796,18 @@ static ssize_t trans_table_show(struct device *dev, · 1 unmodified line
764796 struct device_attribute *attr, char *buf)
765797 {
766798 struct thermal_cooling_device *cdev = to_cooling_device(dev);
767− struct cooling_dev_stats *stats = cdev->stats;
799+ struct cooling_dev_stats *stats;
768800 ssize_t len = 0;
769801 int i, j;
770802
803+ mutex_lock(&cdev->lock);
804+
805+ stats = cdev->stats;
806+ if (!stats) {
807+ len = -ENODATA;
808+ goto unlock;
809+ }
810+
771811 len += snprintf(buf + len, PAGE_SIZE - len, " From : To\n");
772812 len += snprintf(buf + len, PAGE_SIZE - len, " : ");
773813 for (i = 0; i <= cdev->max_state; i++) {
@@ -775,8 +815,10 @@ static ssize_t trans_table_show(struct device *dev, · 1 unmodified line
775815 break;
776816 len += snprintf(buf + len, PAGE_SIZE - len, "state%2u ", i);
777817 }
778− if (len >= PAGE_SIZE)
779− return PAGE_SIZE;
818+ if (len >= PAGE_SIZE) {
819+ len = PAGE_SIZE;
820+ goto unlock;
821+ }
780822
781823 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
782824
@@ -799,8 +841,12 @@ static ssize_t trans_table_show(struct device *dev, · 16 unmodified lines
799841
800842 if (len >= PAGE_SIZE) {
801843 pr_warn_once("Thermal transition table exceeds PAGE_SIZE. Disabling\n");
802− return -EFBIG;
844+ len = -EFBIG;
803845 }
846+
847+unlock:
848+ mutex_unlock(&cdev->lock);
849+
804850 return len;
805851 }
806852
@@ -830,6 +876,8 @@ static void cooling_device_stats_setup(struct thermal_cooling_device *cdev) · 23 unmodified lines
830876 unsigned long states = cdev->max_state + 1;
831877 int var;
832878
879+ lockdep_assert_held(&cdev->lock);
880+
833881 var = sizeof(*stats);
834882 var += sizeof(*stats->time_in_state) * states;
835883 var += sizeof(*stats->trans_table) * states * states;
@@ -855,6 +903,8 @@ out: · 19 unmodified lines
855903
856904 static void cooling_device_stats_destroy(struct thermal_cooling_device *cdev)
857905 {
906+ lockdep_assert_held(&cdev->lock);
907+
858908 kfree(cdev->stats);
859909 cdev->stats = NULL;
860910 }
@@ -879,6 +929,12 @@ void thermal_cooling_device_destroy_sysfs(struct thermal_cooling_device *cdev) · 18 unmodified lines
879929 cooling_device_stats_destroy(cdev);
880930 }
881931
932+void thermal_cooling_device_stats_reinit(struct thermal_cooling_device *cdev)
933+{
934+ cooling_device_stats_destroy(cdev);
935+ cooling_device_stats_setup(cdev);
936+}
937+
882938 /* these helper will be used only at the time of bindig */
883939 ssize_t
884940 trip_point_show(struct device *dev, struct device_attribute *attr, char *buf)
include/linux/thermal.h+1−0
@@ -384,6 +384,7 @@ devm_thermal_of_cooling_device_register(struct device *dev, · 383 unmodified lines
384384 struct device_node *np,
385385 char *type, void *devdata,
386386 const struct thermal_cooling_device_ops *ops);
387+void thermal_cooling_device_update(struct thermal_cooling_device *);
387388 void thermal_cooling_device_unregister(struct thermal_cooling_device *);
388389 struct thermal_zone_device *thermal_zone_get_zone_by_name(const char *name);
389390 int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp);