aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/cpufreq/cpufreq-dt.c1
-rw-r--r--drivers/cpufreq/cpufreq.c7
-rw-r--r--drivers/cpufreq/cpufreq_governor.c3
-rw-r--r--drivers/cpufreq/intel_pstate.c8
-rw-r--r--include/linux/cpufreq.h20
-rw-r--r--kernel/sched/cpufreq_schedutil.c86
-rw-r--r--kernel/sched/deadline.c2
-rw-r--r--kernel/sched/fair.c8
-rw-r--r--kernel/sched/rt.c2
-rw-r--r--kernel/sched/sched.h10
10 files changed, 116 insertions, 31 deletions
diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c
index fef3c2160691..d83ab94d041a 100644
--- a/drivers/cpufreq/cpufreq-dt.c
+++ b/drivers/cpufreq/cpufreq-dt.c
@@ -274,6 +274,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)
274 transition_latency = CPUFREQ_ETERNAL; 274 transition_latency = CPUFREQ_ETERNAL;
275 275
276 policy->cpuinfo.transition_latency = transition_latency; 276 policy->cpuinfo.transition_latency = transition_latency;
277 policy->dvfs_possible_from_any_cpu = true;
277 278
278 return 0; 279 return 0;
279 280
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index c7ae67d6886d..ea43b147a7fe 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1843,9 +1843,10 @@ EXPORT_SYMBOL(cpufreq_unregister_notifier);
1843 * twice in parallel for the same policy and that it will never be called in 1843 * twice in parallel for the same policy and that it will never be called in
1844 * parallel with either ->target() or ->target_index() for the same policy. 1844 * parallel with either ->target() or ->target_index() for the same policy.
1845 * 1845 *
1846 * If CPUFREQ_ENTRY_INVALID is returned by the driver's ->fast_switch() 1846 * Returns the actual frequency set for the CPU.
1847 * callback to indicate an error condition, the hardware configuration must be 1847 *
1848 * preserved. 1848 * If 0 is returned by the driver's ->fast_switch() callback to indicate an
1849 * error condition, the hardware configuration must be preserved.
1849 */ 1850 */
1850unsigned int cpufreq_driver_fast_switch(struct cpufreq_policy *policy, 1851unsigned int cpufreq_driver_fast_switch(struct cpufreq_policy *policy,
1851 unsigned int target_freq) 1852 unsigned int target_freq)
diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c
index eed069ecfd5e..58d4f4e1ad6a 100644
--- a/drivers/cpufreq/cpufreq_governor.c
+++ b/drivers/cpufreq/cpufreq_governor.c
@@ -272,6 +272,9 @@ static void dbs_update_util_handler(struct update_util_data *data, u64 time,
272 struct policy_dbs_info *policy_dbs = cdbs->policy_dbs; 272 struct policy_dbs_info *policy_dbs = cdbs->policy_dbs;
273 u64 delta_ns, lst; 273 u64 delta_ns, lst;
274 274
275 if (!cpufreq_can_do_remote_dvfs(policy_dbs->policy))
276 return;
277
275 /* 278 /*
276 * The work may not be allowed to be queued up right now. 279 * The work may not be allowed to be queued up right now.
277 * Possible reasons: 280 * Possible reasons:
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index 04dd5f46803d..0c50637e6bda 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -1746,6 +1746,10 @@ static void intel_pstate_update_util_pid(struct update_util_data *data,
1746 struct cpudata *cpu = container_of(data, struct cpudata, update_util); 1746 struct cpudata *cpu = container_of(data, struct cpudata, update_util);
1747 u64 delta_ns = time - cpu->sample.time; 1747 u64 delta_ns = time - cpu->sample.time;
1748 1748
1749 /* Don't allow remote callbacks */
1750 if (smp_processor_id() != cpu->cpu)
1751 return;
1752
1749 if ((s64)delta_ns < pid_params.sample_rate_ns) 1753 if ((s64)delta_ns < pid_params.sample_rate_ns)
1750 return; 1754 return;
1751 1755
@@ -1763,6 +1767,10 @@ static void intel_pstate_update_util(struct update_util_data *data, u64 time,
1763 struct cpudata *cpu = container_of(data, struct cpudata, update_util); 1767 struct cpudata *cpu = container_of(data, struct cpudata, update_util);
1764 u64 delta_ns; 1768 u64 delta_ns;
1765 1769
1770 /* Don't allow remote callbacks */
1771 if (smp_processor_id() != cpu->cpu)
1772 return;
1773
1766 if (flags & SCHED_CPUFREQ_IOWAIT) { 1774 if (flags & SCHED_CPUFREQ_IOWAIT) {
1767 cpu->iowait_boost = int_tofp(1); 1775 cpu->iowait_boost = int_tofp(1);
1768 } else if (cpu->iowait_boost) { 1776 } else if (cpu->iowait_boost) {
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 5f40522ec98c..537ff842ff73 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -127,6 +127,15 @@ struct cpufreq_policy {
127 */ 127 */
128 unsigned int transition_delay_us; 128 unsigned int transition_delay_us;
129 129
130 /*
131 * Remote DVFS flag (Not added to the driver structure as we don't want
132 * to access another structure from scheduler hotpath).
133 *
134 * Should be set if CPUs can do DVFS on behalf of other CPUs from
135 * different cpufreq policies.
136 */
137 bool dvfs_possible_from_any_cpu;
138
130 /* Cached frequency lookup from cpufreq_driver_resolve_freq. */ 139 /* Cached frequency lookup from cpufreq_driver_resolve_freq. */
131 unsigned int cached_target_freq; 140 unsigned int cached_target_freq;
132 int cached_resolved_idx; 141 int cached_resolved_idx;
@@ -562,6 +571,17 @@ struct governor_attr {
562 size_t count); 571 size_t count);
563}; 572};
564 573
574static inline bool cpufreq_can_do_remote_dvfs(struct cpufreq_policy *policy)
575{
576 /*
577 * Allow remote callbacks if:
578 * - dvfs_possible_from_any_cpu flag is set
579 * - the local and remote CPUs share cpufreq policy
580 */
581 return policy->dvfs_possible_from_any_cpu ||
582 cpumask_test_cpu(smp_processor_id(), policy->cpus);
583}
584
565/********************************************************************* 585/*********************************************************************
566 * FREQUENCY TABLE HELPERS * 586 * FREQUENCY TABLE HELPERS *
567 *********************************************************************/ 587 *********************************************************************/
diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c
index 45fcf21ad685..9209d83ecdcf 100644
--- a/kernel/sched/cpufreq_schedutil.c
+++ b/kernel/sched/cpufreq_schedutil.c
@@ -52,9 +52,11 @@ struct sugov_policy {
52struct sugov_cpu { 52struct sugov_cpu {
53 struct update_util_data update_util; 53 struct update_util_data update_util;
54 struct sugov_policy *sg_policy; 54 struct sugov_policy *sg_policy;
55 unsigned int cpu;
55 56
56 unsigned long iowait_boost; 57 bool iowait_boost_pending;
57 unsigned long iowait_boost_max; 58 unsigned int iowait_boost;
59 unsigned int iowait_boost_max;
58 u64 last_update; 60 u64 last_update;
59 61
60 /* The fields below are only needed when sharing a policy. */ 62 /* The fields below are only needed when sharing a policy. */
@@ -76,6 +78,26 @@ static bool sugov_should_update_freq(struct sugov_policy *sg_policy, u64 time)
76{ 78{
77 s64 delta_ns; 79 s64 delta_ns;
78 80
81 /*
82 * Since cpufreq_update_util() is called with rq->lock held for
83 * the @target_cpu, our per-cpu data is fully serialized.
84 *
85 * However, drivers cannot in general deal with cross-cpu
86 * requests, so while get_next_freq() will work, our
87 * sugov_update_commit() call may not for the fast switching platforms.
88 *
89 * Hence stop here for remote requests if they aren't supported
90 * by the hardware, as calculating the frequency is pointless if
91 * we cannot in fact act on it.
92 *
93 * For the slow switching platforms, the kthread is always scheduled on
94 * the right set of CPUs and any CPU can find the next frequency and
95 * schedule the kthread.
96 */
97 if (sg_policy->policy->fast_switch_enabled &&
98 !cpufreq_can_do_remote_dvfs(sg_policy->policy))
99 return false;
100
79 if (sg_policy->work_in_progress) 101 if (sg_policy->work_in_progress)
80 return false; 102 return false;
81 103
@@ -106,7 +128,7 @@ static void sugov_update_commit(struct sugov_policy *sg_policy, u64 time,
106 128
107 if (policy->fast_switch_enabled) { 129 if (policy->fast_switch_enabled) {
108 next_freq = cpufreq_driver_fast_switch(policy, next_freq); 130 next_freq = cpufreq_driver_fast_switch(policy, next_freq);
109 if (next_freq == CPUFREQ_ENTRY_INVALID) 131 if (!next_freq)
110 return; 132 return;
111 133
112 policy->cur = next_freq; 134 policy->cur = next_freq;
@@ -154,12 +176,12 @@ static unsigned int get_next_freq(struct sugov_policy *sg_policy,
154 return cpufreq_driver_resolve_freq(policy, freq); 176 return cpufreq_driver_resolve_freq(policy, freq);
155} 177}
156 178
157static void sugov_get_util(unsigned long *util, unsigned long *max) 179static void sugov_get_util(unsigned long *util, unsigned long *max, int cpu)
158{ 180{
159 struct rq *rq = this_rq(); 181 struct rq *rq = cpu_rq(cpu);
160 unsigned long cfs_max; 182 unsigned long cfs_max;
161 183
162 cfs_max = arch_scale_cpu_capacity(NULL, smp_processor_id()); 184 cfs_max = arch_scale_cpu_capacity(NULL, cpu);
163 185
164 *util = min(rq->cfs.avg.util_avg, cfs_max); 186 *util = min(rq->cfs.avg.util_avg, cfs_max);
165 *max = cfs_max; 187 *max = cfs_max;
@@ -169,30 +191,54 @@ static void sugov_set_iowait_boost(struct sugov_cpu *sg_cpu, u64 time,
169 unsigned int flags) 191 unsigned int flags)
170{ 192{
171 if (flags & SCHED_CPUFREQ_IOWAIT) { 193 if (flags & SCHED_CPUFREQ_IOWAIT) {
172 sg_cpu->iowait_boost = sg_cpu->iowait_boost_max; 194 if (sg_cpu->iowait_boost_pending)
195 return;
196
197 sg_cpu->iowait_boost_pending = true;
198
199 if (sg_cpu->iowait_boost) {
200 sg_cpu->iowait_boost <<= 1;
201 if (sg_cpu->iowait_boost > sg_cpu->iowait_boost_max)
202 sg_cpu->iowait_boost = sg_cpu->iowait_boost_max;
203 } else {
204 sg_cpu->iowait_boost = sg_cpu->sg_policy->policy->min;
205 }
173 } else if (sg_cpu->iowait_boost) { 206 } else if (sg_cpu->iowait_boost) {
174 s64 delta_ns = time - sg_cpu->last_update; 207 s64 delta_ns = time - sg_cpu->last_update;
175 208
176 /* Clear iowait_boost if the CPU apprears to have been idle. */ 209 /* Clear iowait_boost if the CPU apprears to have been idle. */
177 if (delta_ns > TICK_NSEC) 210 if (delta_ns > TICK_NSEC) {
178 sg_cpu->iowait_boost = 0; 211 sg_cpu->iowait_boost = 0;
212 sg_cpu->iowait_boost_pending = false;
213 }
179 } 214 }
180} 215}
181 216
182static void sugov_iowait_boost(struct sugov_cpu *sg_cpu, unsigned long *util, 217static void sugov_iowait_boost(struct sugov_cpu *sg_cpu, unsigned long *util,
183 unsigned long *max) 218 unsigned long *max)
184{ 219{
185 unsigned long boost_util = sg_cpu->iowait_boost; 220 unsigned int boost_util, boost_max;
186 unsigned long boost_max = sg_cpu->iowait_boost_max;
187 221
188 if (!boost_util) 222 if (!sg_cpu->iowait_boost)
189 return; 223 return;
190 224
225 if (sg_cpu->iowait_boost_pending) {
226 sg_cpu->iowait_boost_pending = false;
227 } else {
228 sg_cpu->iowait_boost >>= 1;
229 if (sg_cpu->iowait_boost < sg_cpu->sg_policy->policy->min) {
230 sg_cpu->iowait_boost = 0;
231 return;
232 }
233 }
234
235 boost_util = sg_cpu->iowait_boost;
236 boost_max = sg_cpu->iowait_boost_max;
237
191 if (*util * boost_max < *max * boost_util) { 238 if (*util * boost_max < *max * boost_util) {
192 *util = boost_util; 239 *util = boost_util;
193 *max = boost_max; 240 *max = boost_max;
194 } 241 }
195 sg_cpu->iowait_boost >>= 1;
196} 242}
197 243
198#ifdef CONFIG_NO_HZ_COMMON 244#ifdef CONFIG_NO_HZ_COMMON
@@ -229,7 +275,7 @@ static void sugov_update_single(struct update_util_data *hook, u64 time,
229 if (flags & SCHED_CPUFREQ_RT_DL) { 275 if (flags & SCHED_CPUFREQ_RT_DL) {
230 next_f = policy->cpuinfo.max_freq; 276 next_f = policy->cpuinfo.max_freq;
231 } else { 277 } else {
232 sugov_get_util(&util, &max); 278 sugov_get_util(&util, &max, sg_cpu->cpu);
233 sugov_iowait_boost(sg_cpu, &util, &max); 279 sugov_iowait_boost(sg_cpu, &util, &max);
234 next_f = get_next_freq(sg_policy, util, max); 280 next_f = get_next_freq(sg_policy, util, max);
235 /* 281 /*
@@ -264,6 +310,7 @@ static unsigned int sugov_next_freq_shared(struct sugov_cpu *sg_cpu, u64 time)
264 delta_ns = time - j_sg_cpu->last_update; 310 delta_ns = time - j_sg_cpu->last_update;
265 if (delta_ns > TICK_NSEC) { 311 if (delta_ns > TICK_NSEC) {
266 j_sg_cpu->iowait_boost = 0; 312 j_sg_cpu->iowait_boost = 0;
313 j_sg_cpu->iowait_boost_pending = false;
267 continue; 314 continue;
268 } 315 }
269 if (j_sg_cpu->flags & SCHED_CPUFREQ_RT_DL) 316 if (j_sg_cpu->flags & SCHED_CPUFREQ_RT_DL)
@@ -290,7 +337,7 @@ static void sugov_update_shared(struct update_util_data *hook, u64 time,
290 unsigned long util, max; 337 unsigned long util, max;
291 unsigned int next_f; 338 unsigned int next_f;
292 339
293 sugov_get_util(&util, &max); 340 sugov_get_util(&util, &max, sg_cpu->cpu);
294 341
295 raw_spin_lock(&sg_policy->update_lock); 342 raw_spin_lock(&sg_policy->update_lock);
296 343
@@ -445,7 +492,11 @@ static int sugov_kthread_create(struct sugov_policy *sg_policy)
445 } 492 }
446 493
447 sg_policy->thread = thread; 494 sg_policy->thread = thread;
448 kthread_bind_mask(thread, policy->related_cpus); 495
496 /* Kthread is bound to all CPUs by default */
497 if (!policy->dvfs_possible_from_any_cpu)
498 kthread_bind_mask(thread, policy->related_cpus);
499
449 init_irq_work(&sg_policy->irq_work, sugov_irq_work); 500 init_irq_work(&sg_policy->irq_work, sugov_irq_work);
450 mutex_init(&sg_policy->work_lock); 501 mutex_init(&sg_policy->work_lock);
451 502
@@ -663,6 +714,11 @@ struct cpufreq_governor *cpufreq_default_governor(void)
663 714
664static int __init sugov_register(void) 715static int __init sugov_register(void)
665{ 716{
717 int cpu;
718
719 for_each_possible_cpu(cpu)
720 per_cpu(sugov_cpu, cpu).cpu = cpu;
721
666 return cpufreq_register_governor(&schedutil_gov); 722 return cpufreq_register_governor(&schedutil_gov);
667} 723}
668fs_initcall(sugov_register); 724fs_initcall(sugov_register);
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
index 755bd3f1a1a9..5c3bf4bd0327 100644
--- a/kernel/sched/deadline.c
+++ b/kernel/sched/deadline.c
@@ -1136,7 +1136,7 @@ static void update_curr_dl(struct rq *rq)
1136 } 1136 }
1137 1137
1138 /* kick cpufreq (see the comment in kernel/sched/sched.h). */ 1138 /* kick cpufreq (see the comment in kernel/sched/sched.h). */
1139 cpufreq_update_this_cpu(rq, SCHED_CPUFREQ_DL); 1139 cpufreq_update_util(rq, SCHED_CPUFREQ_DL);
1140 1140
1141 schedstat_set(curr->se.statistics.exec_max, 1141 schedstat_set(curr->se.statistics.exec_max,
1142 max(curr->se.statistics.exec_max, delta_exec)); 1142 max(curr->se.statistics.exec_max, delta_exec));
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index c95880e216f6..d378d02fdfcb 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -3278,7 +3278,9 @@ static inline void set_tg_cfs_propagate(struct cfs_rq *cfs_rq) {}
3278 3278
3279static inline void cfs_rq_util_change(struct cfs_rq *cfs_rq) 3279static inline void cfs_rq_util_change(struct cfs_rq *cfs_rq)
3280{ 3280{
3281 if (&this_rq()->cfs == cfs_rq) { 3281 struct rq *rq = rq_of(cfs_rq);
3282
3283 if (&rq->cfs == cfs_rq) {
3282 /* 3284 /*
3283 * There are a few boundary cases this might miss but it should 3285 * There are a few boundary cases this might miss but it should
3284 * get called often enough that that should (hopefully) not be 3286 * get called often enough that that should (hopefully) not be
@@ -3295,7 +3297,7 @@ static inline void cfs_rq_util_change(struct cfs_rq *cfs_rq)
3295 * 3297 *
3296 * See cpu_util(). 3298 * See cpu_util().
3297 */ 3299 */
3298 cpufreq_update_util(rq_of(cfs_rq), 0); 3300 cpufreq_update_util(rq, 0);
3299 } 3301 }
3300} 3302}
3301 3303
@@ -4875,7 +4877,7 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int flags)
4875 * passed. 4877 * passed.
4876 */ 4878 */
4877 if (p->in_iowait) 4879 if (p->in_iowait)
4878 cpufreq_update_this_cpu(rq, SCHED_CPUFREQ_IOWAIT); 4880 cpufreq_update_util(rq, SCHED_CPUFREQ_IOWAIT);
4879 4881
4880 for_each_sched_entity(se) { 4882 for_each_sched_entity(se) {
4881 if (se->on_rq) 4883 if (se->on_rq)
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index 45caf937ef90..0af5ca9e3e3f 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -970,7 +970,7 @@ static void update_curr_rt(struct rq *rq)
970 return; 970 return;
971 971
972 /* Kick cpufreq (see the comment in kernel/sched/sched.h). */ 972 /* Kick cpufreq (see the comment in kernel/sched/sched.h). */
973 cpufreq_update_this_cpu(rq, SCHED_CPUFREQ_RT); 973 cpufreq_update_util(rq, SCHED_CPUFREQ_RT);
974 974
975 schedstat_set(curr->se.statistics.exec_max, 975 schedstat_set(curr->se.statistics.exec_max,
976 max(curr->se.statistics.exec_max, delta_exec)); 976 max(curr->se.statistics.exec_max, delta_exec));
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index eeef1a3086d1..aa9d5b87b4f8 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -2070,19 +2070,13 @@ static inline void cpufreq_update_util(struct rq *rq, unsigned int flags)
2070{ 2070{
2071 struct update_util_data *data; 2071 struct update_util_data *data;
2072 2072
2073 data = rcu_dereference_sched(*this_cpu_ptr(&cpufreq_update_util_data)); 2073 data = rcu_dereference_sched(*per_cpu_ptr(&cpufreq_update_util_data,
2074 cpu_of(rq)));
2074 if (data) 2075 if (data)
2075 data->func(data, rq_clock(rq), flags); 2076 data->func(data, rq_clock(rq), flags);
2076} 2077}
2077
2078static inline void cpufreq_update_this_cpu(struct rq *rq, unsigned int flags)
2079{
2080 if (cpu_of(rq) == smp_processor_id())
2081 cpufreq_update_util(rq, flags);
2082}
2083#else 2078#else
2084static inline void cpufreq_update_util(struct rq *rq, unsigned int flags) {} 2079static inline void cpufreq_update_util(struct rq *rq, unsigned int flags) {}
2085static inline void cpufreq_update_this_cpu(struct rq *rq, unsigned int flags) {}
2086#endif /* CONFIG_CPU_FREQ */ 2080#endif /* CONFIG_CPU_FREQ */
2087 2081
2088#ifdef arch_scale_freq_capacity 2082#ifdef arch_scale_freq_capacity