summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2019-10-24 20:41:40 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2019-10-25 05:33:48 -0400
commita1bb46c36ce389d4a24a42e5b6047b0626caa3ea (patch)
tree26c9929b77ee92690a6744308e51ebd99c3f755c
parent6941051d3028963c3b0b3fcdd0815f2b51b957bb (diff)
ACPI: processor: Add QoS requests for all CPUs
The _PPC change notifications from the platform firmware are per-CPU, so acpi_processor_ppc_init() needs to add a frequency QoS request for each CPU covered by a cpufreq policy to take all of them into account. Even though ACPI thermal control of CPUs sets frequency limits per processor package, it also needs a frequency QoS request for each CPU in a cpufreq policy in case some of them are taken offline and the frequency limit needs to be set through the remaining online ones (this is slightly excessive, because all CPUs covered by one cpufreq policy will set the same frequency limit through their QoS requests, but it is not incorrect). Modify the code in accordance with the above observations. Fixes: d15ce412737a ("ACPI: cpufreq: Switch to QoS requests instead of cpufreq notifier") Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
-rw-r--r--drivers/acpi/processor_perflib.c34
-rw-r--r--drivers/acpi/processor_thermal.c34
2 files changed, 42 insertions, 26 deletions
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index 753e171de006..5909e8fa4013 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -159,26 +159,34 @@ void acpi_processor_ignore_ppc_init(void)
159 159
160void acpi_processor_ppc_init(struct cpufreq_policy *policy) 160void acpi_processor_ppc_init(struct cpufreq_policy *policy)
161{ 161{
162 int cpu = policy->cpu; 162 unsigned int cpu;
163 struct acpi_processor *pr = per_cpu(processors, cpu);
164 int ret;
165 163
166 if (!pr) 164 for_each_cpu(cpu, policy->related_cpus) {
167 return; 165 struct acpi_processor *pr = per_cpu(processors, cpu);
166 int ret;
167
168 if (!pr)
169 continue;
168 170
169 ret = freq_qos_add_request(&policy->constraints, &pr->perflib_req, 171 ret = freq_qos_add_request(&policy->constraints,
170 FREQ_QOS_MAX, INT_MAX); 172 &pr->perflib_req,
171 if (ret < 0) 173 FREQ_QOS_MAX, INT_MAX);
172 pr_err("Failed to add freq constraint for CPU%d (%d)\n", cpu, 174 if (ret < 0)
173 ret); 175 pr_err("Failed to add freq constraint for CPU%d (%d)\n",
176 cpu, ret);
177 }
174} 178}
175 179
176void acpi_processor_ppc_exit(struct cpufreq_policy *policy) 180void acpi_processor_ppc_exit(struct cpufreq_policy *policy)
177{ 181{
178 struct acpi_processor *pr = per_cpu(processors, policy->cpu); 182 unsigned int cpu;
179 183
180 if (pr) 184 for_each_cpu(cpu, policy->related_cpus) {
181 freq_qos_remove_request(&pr->perflib_req); 185 struct acpi_processor *pr = per_cpu(processors, cpu);
186
187 if (pr)
188 freq_qos_remove_request(&pr->perflib_req);
189 }
182} 190}
183 191
184static int acpi_processor_get_performance_control(struct acpi_processor *pr) 192static int acpi_processor_get_performance_control(struct acpi_processor *pr)
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
index c77a5b1fb107..41feb88ee92d 100644
--- a/drivers/acpi/processor_thermal.c
+++ b/drivers/acpi/processor_thermal.c
@@ -127,26 +127,34 @@ static int cpufreq_set_cur_state(unsigned int cpu, int state)
127 127
128void acpi_thermal_cpufreq_init(struct cpufreq_policy *policy) 128void acpi_thermal_cpufreq_init(struct cpufreq_policy *policy)
129{ 129{
130 int cpu = policy->cpu; 130 unsigned int cpu;
131 struct acpi_processor *pr = per_cpu(processors, cpu);
132 int ret;
133 131
134 if (!pr) 132 for_each_cpu(cpu, policy->related_cpus) {
135 return; 133 struct acpi_processor *pr = per_cpu(processors, cpu);
134 int ret;
135
136 if (!pr)
137 continue;
136 138
137 ret = freq_qos_add_request(&policy->constraints, &pr->thermal_req, 139 ret = freq_qos_add_request(&policy->constraints,
138 FREQ_QOS_MAX, INT_MAX); 140 &pr->thermal_req,
139 if (ret < 0) 141 FREQ_QOS_MAX, INT_MAX);
140 pr_err("Failed to add freq constraint for CPU%d (%d)\n", cpu, 142 if (ret < 0)
141 ret); 143 pr_err("Failed to add freq constraint for CPU%d (%d)\n",
144 cpu, ret);
145 }
142} 146}
143 147
144void acpi_thermal_cpufreq_exit(struct cpufreq_policy *policy) 148void acpi_thermal_cpufreq_exit(struct cpufreq_policy *policy)
145{ 149{
146 struct acpi_processor *pr = per_cpu(processors, policy->cpu); 150 unsigned int cpu;
151
152 for_each_cpu(cpu, policy->related_cpus) {
153 struct acpi_processor *pr = per_cpu(processors, policy->cpu);
147 154
148 if (pr) 155 if (pr)
149 freq_qos_remove_request(&pr->thermal_req); 156 freq_qos_remove_request(&pr->thermal_req);
157 }
150} 158}
151#else /* ! CONFIG_CPU_FREQ */ 159#else /* ! CONFIG_CPU_FREQ */
152static int cpufreq_get_max_state(unsigned int cpu) 160static int cpufreq_get_max_state(unsigned int cpu)