hc
2023-12-06 08f87f769b595151be1afeff53e144f543faa614
kernel/drivers/acpi/processor_perflib.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * processor_perflib.c - ACPI Processor P-States Library ($Revision: 71 $)
34 *
....@@ -6,20 +7,6 @@
67 * Copyright (C) 2004 Dominik Brodowski <linux@brodo.de>
78 * Copyright (C) 2004 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
89 * - Added processor hotplug support
9
- *
10
- *
11
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
12
- *
13
- * This program is free software; you can redistribute it and/or modify
14
- * it under the terms of the GNU General Public License as published by
15
- * the Free Software Foundation; either version 2 of the License, or (at
16
- * your option) any later version.
17
- *
18
- * This program is distributed in the hope that it will be useful, but
19
- * WITHOUT ANY WARRANTY; without even the implied warranty of
20
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21
- * General Public License for more details.
22
- *
2310 */
2411
2512 #include <linux/kernel.h>
....@@ -63,57 +50,13 @@
6350 MODULE_PARM_DESC(ignore_ppc, "If the frequency of your machine gets wrongly" \
6451 "limited by BIOS, this should help");
6552
66
-#define PPC_REGISTERED 1
67
-#define PPC_IN_USE 2
68
-
69
-static int acpi_processor_ppc_status;
70
-
71
-static int acpi_processor_ppc_notifier(struct notifier_block *nb,
72
- unsigned long event, void *data)
73
-{
74
- struct cpufreq_policy *policy = data;
75
- struct acpi_processor *pr;
76
- unsigned int ppc = 0;
77
-
78
- if (ignore_ppc < 0)
79
- ignore_ppc = 0;
80
-
81
- if (ignore_ppc)
82
- return 0;
83
-
84
- if (event != CPUFREQ_ADJUST)
85
- return 0;
86
-
87
- mutex_lock(&performance_mutex);
88
-
89
- pr = per_cpu(processors, policy->cpu);
90
- if (!pr || !pr->performance)
91
- goto out;
92
-
93
- ppc = (unsigned int)pr->performance_platform_limit;
94
-
95
- if (ppc >= pr->performance->state_count)
96
- goto out;
97
-
98
- cpufreq_verify_within_limits(policy, 0,
99
- pr->performance->states[ppc].
100
- core_frequency * 1000);
101
-
102
- out:
103
- mutex_unlock(&performance_mutex);
104
-
105
- return 0;
106
-}
107
-
108
-static struct notifier_block acpi_ppc_notifier_block = {
109
- .notifier_call = acpi_processor_ppc_notifier,
110
-};
53
+static bool acpi_processor_ppc_in_use;
11154
11255 static int acpi_processor_get_platform_limit(struct acpi_processor *pr)
11356 {
11457 acpi_status status = 0;
11558 unsigned long long ppc = 0;
116
-
59
+ int ret;
11760
11861 if (!pr)
11962 return -EINVAL;
....@@ -125,7 +68,7 @@
12568 status = acpi_evaluate_integer(pr->handle, "_PPC", NULL, &ppc);
12669
12770 if (status != AE_NOT_FOUND)
128
- acpi_processor_ppc_status |= PPC_IN_USE;
71
+ acpi_processor_ppc_in_use = true;
12972
13073 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
13174 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PPC"));
....@@ -136,6 +79,17 @@
13679 (int)ppc, ppc ? "" : "not");
13780
13881 pr->performance_platform_limit = (int)ppc;
82
+
83
+ if (ppc >= pr->performance->state_count ||
84
+ unlikely(!freq_qos_request_active(&pr->perflib_req)))
85
+ return 0;
86
+
87
+ ret = freq_qos_update_request(&pr->perflib_req,
88
+ pr->performance->states[ppc].core_frequency * 1000);
89
+ if (ret < 0) {
90
+ pr_warn("Failed to update perflib freq constraint: CPU%d (%d)\n",
91
+ pr->id, ret);
92
+ }
13993
14094 return 0;
14195 }
....@@ -181,7 +135,7 @@
181135 acpi_processor_ppc_ost(pr->handle, 0);
182136 }
183137 if (ret >= 0)
184
- cpufreq_update_policy(pr->id);
138
+ cpufreq_update_limits(pr->id);
185139 }
186140
187141 int acpi_processor_get_bios_limit(int cpu, unsigned int *limit)
....@@ -197,23 +151,42 @@
197151 }
198152 EXPORT_SYMBOL(acpi_processor_get_bios_limit);
199153
200
-void acpi_processor_ppc_init(void)
154
+void acpi_processor_ignore_ppc_init(void)
201155 {
202
- if (!cpufreq_register_notifier
203
- (&acpi_ppc_notifier_block, CPUFREQ_POLICY_NOTIFIER))
204
- acpi_processor_ppc_status |= PPC_REGISTERED;
205
- else
206
- printk(KERN_DEBUG
207
- "Warning: Processor Platform Limit not supported.\n");
156
+ if (ignore_ppc < 0)
157
+ ignore_ppc = 0;
208158 }
209159
210
-void acpi_processor_ppc_exit(void)
160
+void acpi_processor_ppc_init(struct cpufreq_policy *policy)
211161 {
212
- if (acpi_processor_ppc_status & PPC_REGISTERED)
213
- cpufreq_unregister_notifier(&acpi_ppc_notifier_block,
214
- CPUFREQ_POLICY_NOTIFIER);
162
+ unsigned int cpu;
215163
216
- acpi_processor_ppc_status &= ~PPC_REGISTERED;
164
+ for_each_cpu(cpu, policy->related_cpus) {
165
+ struct acpi_processor *pr = per_cpu(processors, cpu);
166
+ int ret;
167
+
168
+ if (!pr)
169
+ continue;
170
+
171
+ ret = freq_qos_add_request(&policy->constraints,
172
+ &pr->perflib_req,
173
+ FREQ_QOS_MAX, INT_MAX);
174
+ if (ret < 0)
175
+ pr_err("Failed to add freq constraint for CPU%d (%d)\n",
176
+ cpu, ret);
177
+ }
178
+}
179
+
180
+void acpi_processor_ppc_exit(struct cpufreq_policy *policy)
181
+{
182
+ unsigned int cpu;
183
+
184
+ for_each_cpu(cpu, policy->related_cpus) {
185
+ struct acpi_processor *pr = per_cpu(processors, cpu);
186
+
187
+ if (pr)
188
+ freq_qos_remove_request(&pr->perflib_req);
189
+ }
217190 }
218191
219192 static int acpi_processor_get_performance_control(struct acpi_processor *pr)
....@@ -381,7 +354,7 @@
381354 (u32) px->control, (u32) px->status));
382355
383356 /*
384
- * Check that ACPI's u64 MHz will be valid as u32 KHz in cpufreq
357
+ * Check that ACPI's u64 MHz will be valid as u32 KHz in cpufreq
385358 */
386359 if (!px->core_frequency ||
387360 ((u32)(px->core_frequency * 1000) !=
....@@ -490,7 +463,7 @@
490463 static int is_done = 0;
491464 int result;
492465
493
- if (!(acpi_processor_ppc_status & PPC_REGISTERED))
466
+ if (!acpi_processor_cpufreq_init)
494467 return -EBUSY;
495468
496469 if (!try_module_get(calling_module))
....@@ -526,7 +499,7 @@
526499 * we can allow the cpufreq driver to be rmmod'ed. */
527500 is_done = 1;
528501
529
- if (!(acpi_processor_ppc_status & PPC_IN_USE))
502
+ if (!acpi_processor_ppc_in_use)
530503 module_put(calling_module);
531504
532505 return 0;
....@@ -654,7 +627,7 @@
654627 goto err_ret;
655628
656629 /*
657
- * Now that we have _PSD data from all CPUs, lets setup P-state
630
+ * Now that we have _PSD data from all CPUs, lets setup P-state
658631 * domain info.
659632 */
660633 for_each_possible_cpu(i) {
....@@ -720,7 +693,7 @@
720693 if (match_pdomain->domain != pdomain->domain)
721694 continue;
722695
723
- match_pr->performance->shared_type =
696
+ match_pr->performance->shared_type =
724697 pr->performance->shared_type;
725698 cpumask_copy(match_pr->performance->shared_cpu_map,
726699 pr->performance->shared_cpu_map);
....@@ -755,7 +728,7 @@
755728 {
756729 struct acpi_processor *pr;
757730
758
- if (!(acpi_processor_ppc_status & PPC_REGISTERED))
731
+ if (!acpi_processor_cpufreq_init)
759732 return -EINVAL;
760733
761734 mutex_lock(&performance_mutex);