blob: d14f35bc87c61a81c1909b1bd77e0883df23855e [file] [log] [blame]
Rafael J. Wysockib1d09762016-04-02 01:09:12 +02001/*
2 * CPUFreq governor based on scheduler-provided CPU utilization data.
3 *
4 * Copyright (C) 2016, Intel Corporation
5 * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
Viresh Kumar87ecf322016-05-18 17:55:28 +053012#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
13
Rafael J. Wysockib1d09762016-04-02 01:09:12 +020014#include <linux/cpufreq.h>
Viresh Kumara231c652016-11-15 13:53:22 +053015#include <linux/kthread.h>
Rafael J. Wysockib1d09762016-04-02 01:09:12 +020016#include <linux/slab.h>
17#include <trace/events/power.h>
18
19#include "sched.h"
20
Viresh Kumara231c652016-11-15 13:53:22 +053021#define SUGOV_KTHREAD_PRIORITY 50
22
Rafael J. Wysockib1d09762016-04-02 01:09:12 +020023struct sugov_tunables {
24 struct gov_attr_set attr_set;
25 unsigned int rate_limit_us;
Rohit Gupta30249632017-02-02 18:39:07 -080026 unsigned int hispeed_freq;
Saravana Kannand0a7c6b2017-05-23 17:26:32 -070027 bool pl;
Rafael J. Wysockib1d09762016-04-02 01:09:12 +020028};
29
30struct sugov_policy {
31 struct cpufreq_policy *policy;
32
33 struct sugov_tunables *tunables;
34 struct list_head tunables_hook;
35
36 raw_spinlock_t update_lock; /* For shared policies */
37 u64 last_freq_update_time;
38 s64 freq_update_delay_ns;
Saravana Kannan0f34ee92017-06-28 21:44:14 -070039 u64 last_ws;
40 u64 curr_cycles;
41 u64 last_cyc_update_time;
42 unsigned long avg_cap;
Rafael J. Wysockib1d09762016-04-02 01:09:12 +020043 unsigned int next_freq;
Viresh Kumar55a6d462017-03-02 14:03:20 +053044 unsigned int cached_raw_freq;
Rohit Gupta30249632017-02-02 18:39:07 -080045 unsigned long hispeed_util;
46 unsigned long max;
Rafael J. Wysockib1d09762016-04-02 01:09:12 +020047
48 /* The next fields are only needed if fast switch cannot be used. */
49 struct irq_work irq_work;
Viresh Kumara231c652016-11-15 13:53:22 +053050 struct kthread_work work;
Rafael J. Wysockib1d09762016-04-02 01:09:12 +020051 struct mutex work_lock;
Viresh Kumara231c652016-11-15 13:53:22 +053052 struct kthread_worker worker;
53 struct task_struct *thread;
Rafael J. Wysockib1d09762016-04-02 01:09:12 +020054 bool work_in_progress;
55
56 bool need_freq_update;
57};
58
59struct sugov_cpu {
60 struct update_util_data update_util;
61 struct sugov_policy *sg_policy;
62
Rafael J. Wysocki193d25c2016-09-10 00:00:31 +020063 unsigned long iowait_boost;
64 unsigned long iowait_boost_max;
65 u64 last_update;
Steve Muckled7439bc2016-07-13 13:25:26 -070066
Saravana Kannan05649862017-05-04 19:03:53 -070067 struct sched_walt_cpu_load walt_load;
68
Rafael J. Wysockib1d09762016-04-02 01:09:12 +020069 /* The fields below are only needed when sharing a policy. */
70 unsigned long util;
71 unsigned long max;
Rafael J. Wysockic4568722016-08-16 22:14:55 +020072 unsigned int flags;
Vikram Mulukutla857cffa2017-05-04 19:47:06 -070073 unsigned int cpu;
Rafael J. Wysockib1d09762016-04-02 01:09:12 +020074};
75
76static DEFINE_PER_CPU(struct sugov_cpu, sugov_cpu);
77
78/************************ Governor internals ***********************/
79
80static bool sugov_should_update_freq(struct sugov_policy *sg_policy, u64 time)
81{
82 s64 delta_ns;
83
Rafael J. Wysockib1d09762016-04-02 01:09:12 +020084 if (unlikely(sg_policy->need_freq_update)) {
85 sg_policy->need_freq_update = false;
86 /*
87 * This happens when limits change, so forget the previous
88 * next_freq value and force an update.
89 */
90 sg_policy->next_freq = UINT_MAX;
91 return true;
92 }
93
94 delta_ns = time - sg_policy->last_freq_update_time;
95 return delta_ns >= sg_policy->freq_update_delay_ns;
96}
97
98static void sugov_update_commit(struct sugov_policy *sg_policy, u64 time,
99 unsigned int next_freq)
100{
101 struct cpufreq_policy *policy = sg_policy->policy;
102
103 sg_policy->last_freq_update_time = time;
104
105 if (policy->fast_switch_enabled) {
106 if (sg_policy->next_freq == next_freq) {
107 trace_cpu_frequency(policy->cur, smp_processor_id());
108 return;
109 }
110 sg_policy->next_freq = next_freq;
111 next_freq = cpufreq_driver_fast_switch(policy, next_freq);
112 if (next_freq == CPUFREQ_ENTRY_INVALID)
113 return;
114
115 policy->cur = next_freq;
116 trace_cpu_frequency(next_freq, smp_processor_id());
117 } else if (sg_policy->next_freq != next_freq) {
118 sg_policy->next_freq = next_freq;
119 sg_policy->work_in_progress = true;
120 irq_work_queue(&sg_policy->irq_work);
121 }
122}
123
Rohit Gupta30249632017-02-02 18:39:07 -0800124#define TARGET_LOAD 80
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200125/**
126 * get_next_freq - Compute a new frequency for a given cpufreq policy.
Viresh Kumare74f7f12017-03-02 14:03:21 +0530127 * @sg_policy: schedutil policy object to compute the new frequency for.
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200128 * @util: Current CPU utilization.
129 * @max: CPU capacity.
130 *
131 * If the utilization is frequency-invariant, choose the new frequency to be
132 * proportional to it, that is
133 *
134 * next_freq = C * max_freq * util / max
135 *
136 * Otherwise, approximate the would-be frequency-invariant utilization by
137 * util_raw * (curr_freq / max_freq) which leads to
138 *
139 * next_freq = C * curr_freq * util_raw / max
140 *
141 * Take C = 1.25 for the frequency tipping point at (util / max) = 0.8.
Steve Muckled7439bc2016-07-13 13:25:26 -0700142 *
143 * The lowest driver-supported frequency which is equal or greater than the raw
144 * next_freq (as calculated above) is returned, subject to policy min/max and
145 * cpufreq driver limitations.
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200146 */
Viresh Kumare74f7f12017-03-02 14:03:21 +0530147static unsigned int get_next_freq(struct sugov_policy *sg_policy,
148 unsigned long util, unsigned long max)
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200149{
Steve Muckled7439bc2016-07-13 13:25:26 -0700150 struct cpufreq_policy *policy = sg_policy->policy;
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200151 unsigned int freq = arch_scale_freq_invariant() ?
152 policy->cpuinfo.max_freq : policy->cur;
153
Steve Muckled7439bc2016-07-13 13:25:26 -0700154 freq = (freq + (freq >> 2)) * util / max;
155
Viresh Kumar55a6d462017-03-02 14:03:20 +0530156 if (freq == sg_policy->cached_raw_freq && sg_policy->next_freq != UINT_MAX)
Steve Muckled7439bc2016-07-13 13:25:26 -0700157 return sg_policy->next_freq;
Viresh Kumar55a6d462017-03-02 14:03:20 +0530158 sg_policy->cached_raw_freq = freq;
Steve Muckled7439bc2016-07-13 13:25:26 -0700159 return cpufreq_driver_resolve_freq(policy, freq);
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200160}
161
Vikram Mulukutla857cffa2017-05-04 19:47:06 -0700162static void sugov_get_util(unsigned long *util, unsigned long *max, int cpu)
Rafael J. Wysockic4568722016-08-16 22:14:55 +0200163{
Vikram Mulukutla857cffa2017-05-04 19:47:06 -0700164 struct rq *rq = cpu_rq(cpu);
Steve Muckle097cf682016-08-26 11:40:47 -0700165 unsigned long cfs_max;
Saravana Kannan05649862017-05-04 19:03:53 -0700166 struct sugov_cpu *loadcpu = &per_cpu(sugov_cpu, cpu);
Steve Muckle097cf682016-08-26 11:40:47 -0700167
Vikram Mulukutla857cffa2017-05-04 19:47:06 -0700168 cfs_max = arch_scale_cpu_capacity(NULL, cpu);
Rafael J. Wysockic4568722016-08-16 22:14:55 +0200169
170 *util = min(rq->cfs.avg.util_avg, cfs_max);
171 *max = cfs_max;
Saravana Kannan05649862017-05-04 19:03:53 -0700172
173 *util = cpu_util_freq(cpu, &loadcpu->walt_load);
Rafael J. Wysockic4568722016-08-16 22:14:55 +0200174}
175
Rafael J. Wysocki193d25c2016-09-10 00:00:31 +0200176static void sugov_set_iowait_boost(struct sugov_cpu *sg_cpu, u64 time,
177 unsigned int flags)
178{
179 if (flags & SCHED_CPUFREQ_IOWAIT) {
180 sg_cpu->iowait_boost = sg_cpu->iowait_boost_max;
181 } else if (sg_cpu->iowait_boost) {
182 s64 delta_ns = time - sg_cpu->last_update;
183
184 /* Clear iowait_boost if the CPU apprears to have been idle. */
185 if (delta_ns > TICK_NSEC)
186 sg_cpu->iowait_boost = 0;
187 }
188}
189
190static void sugov_iowait_boost(struct sugov_cpu *sg_cpu, unsigned long *util,
191 unsigned long *max)
192{
193 unsigned long boost_util = sg_cpu->iowait_boost;
194 unsigned long boost_max = sg_cpu->iowait_boost_max;
195
196 if (!boost_util)
197 return;
198
199 if (*util * boost_max < *max * boost_util) {
200 *util = boost_util;
201 *max = boost_max;
202 }
203 sg_cpu->iowait_boost >>= 1;
204}
205
Saravana Kannan0f34ee92017-06-28 21:44:14 -0700206static unsigned long freq_to_util(struct sugov_policy *sg_policy,
207 unsigned int freq)
208{
209 return mult_frac(sg_policy->max, freq,
210 sg_policy->policy->cpuinfo.max_freq);
211}
212
213#define KHZ 1000
214static void sugov_track_cycles(struct sugov_policy *sg_policy,
215 unsigned int prev_freq,
216 u64 upto)
217{
218 u64 delta_ns, cycles;
219 /* Track cycles in current window */
220 delta_ns = upto - sg_policy->last_cyc_update_time;
221 cycles = (prev_freq * delta_ns) / (NSEC_PER_SEC / KHZ);
222 sg_policy->curr_cycles += cycles;
223 sg_policy->last_cyc_update_time = upto;
224}
225
226static void sugov_calc_avg_cap(struct sugov_policy *sg_policy, u64 curr_ws,
227 unsigned int prev_freq)
228{
229 u64 last_ws = sg_policy->last_ws;
230 unsigned int avg_freq;
231
232 WARN_ON(curr_ws < last_ws);
233 if (curr_ws <= last_ws)
234 return;
235
236 /* If we skipped some windows */
237 if (curr_ws > (last_ws + sched_ravg_window)) {
238 avg_freq = prev_freq;
239 /* Reset tracking history */
240 sg_policy->last_cyc_update_time = curr_ws;
241 } else {
242 sugov_track_cycles(sg_policy, prev_freq, curr_ws);
243 avg_freq = sg_policy->curr_cycles;
244 avg_freq /= sched_ravg_window / (NSEC_PER_SEC / KHZ);
245 }
246 sg_policy->avg_cap = freq_to_util(sg_policy, avg_freq);
247 sg_policy->curr_cycles = 0;
248 sg_policy->last_ws = curr_ws;
249}
250
Rohit Gupta30249632017-02-02 18:39:07 -0800251#define NL_RATIO 75
252#define HISPEED_LOAD 90
253static void sugov_walt_adjust(struct sugov_cpu *sg_cpu, unsigned long *util,
254 unsigned long *max)
255{
256 struct sugov_policy *sg_policy = sg_cpu->sg_policy;
Rohit Gupta30249632017-02-02 18:39:07 -0800257 bool is_migration = sg_cpu->flags & SCHED_CPUFREQ_INTERCLUSTER_MIG;
258 unsigned long nl = sg_cpu->walt_load.nl;
259 unsigned long cpu_util = sg_cpu->util;
260 bool is_hiload;
261
Saravana Kannan36faa282017-06-28 21:44:56 -0700262 is_hiload = (cpu_util >= mult_frac(sg_policy->avg_cap,
Rohit Gupta30249632017-02-02 18:39:07 -0800263 HISPEED_LOAD,
264 100));
265
Rohit Gupta5573e732017-06-21 10:08:07 -0700266 if (is_hiload && !is_migration)
Rohit Gupta30249632017-02-02 18:39:07 -0800267 *util = max(*util, sg_policy->hispeed_util);
Rohit Gupta30249632017-02-02 18:39:07 -0800268
269 if (is_hiload && nl >= mult_frac(cpu_util, NL_RATIO, 100))
270 *util = *max;
271
Saravana Kannand0a7c6b2017-05-23 17:26:32 -0700272 if (sg_policy->tunables->pl)
273 *util = max(*util, sg_cpu->walt_load.pl);
Rohit Gupta30249632017-02-02 18:39:07 -0800274}
275
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200276static void sugov_update_single(struct update_util_data *hook, u64 time,
Rafael J. Wysockic4568722016-08-16 22:14:55 +0200277 unsigned int flags)
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200278{
279 struct sugov_cpu *sg_cpu = container_of(hook, struct sugov_cpu, update_util);
280 struct sugov_policy *sg_policy = sg_cpu->sg_policy;
281 struct cpufreq_policy *policy = sg_policy->policy;
Rafael J. Wysockic4568722016-08-16 22:14:55 +0200282 unsigned long util, max;
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200283 unsigned int next_f;
284
Rafael J. Wysocki193d25c2016-09-10 00:00:31 +0200285 sugov_set_iowait_boost(sg_cpu, time, flags);
286 sg_cpu->last_update = time;
287
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200288 if (!sugov_should_update_freq(sg_policy, time))
289 return;
290
Saravana Kannan76ef1712017-05-04 19:44:36 -0700291 flags &= ~SCHED_CPUFREQ_RT_DL;
292
Rafael J. Wysockic4568722016-08-16 22:14:55 +0200293 if (flags & SCHED_CPUFREQ_RT_DL) {
294 next_f = policy->cpuinfo.max_freq;
295 } else {
Vikram Mulukutla857cffa2017-05-04 19:47:06 -0700296 sugov_get_util(&util, &max, sg_cpu->cpu);
Rafael J. Wysocki193d25c2016-09-10 00:00:31 +0200297 sugov_iowait_boost(sg_cpu, &util, &max);
Saravana Kannan0f34ee92017-06-28 21:44:14 -0700298 sugov_calc_avg_cap(sg_policy, sg_cpu->walt_load.ws,
299 sg_policy->policy->cur);
Rohit Gupta30249632017-02-02 18:39:07 -0800300 sugov_walt_adjust(sg_cpu, &util, &max);
Viresh Kumare74f7f12017-03-02 14:03:21 +0530301 next_f = get_next_freq(sg_policy, util, max);
Rafael J. Wysockic4568722016-08-16 22:14:55 +0200302 }
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200303 sugov_update_commit(sg_policy, time, next_f);
304}
305
Steve Muckled7439bc2016-07-13 13:25:26 -0700306static unsigned int sugov_next_freq_shared(struct sugov_cpu *sg_cpu,
Rafael J. Wysockic4568722016-08-16 22:14:55 +0200307 unsigned long util, unsigned long max,
308 unsigned int flags)
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200309{
Steve Muckled7439bc2016-07-13 13:25:26 -0700310 struct sugov_policy *sg_policy = sg_cpu->sg_policy;
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200311 struct cpufreq_policy *policy = sg_policy->policy;
312 unsigned int max_f = policy->cpuinfo.max_freq;
313 u64 last_freq_update_time = sg_policy->last_freq_update_time;
314 unsigned int j;
315
Rafael J. Wysockic4568722016-08-16 22:14:55 +0200316 if (flags & SCHED_CPUFREQ_RT_DL)
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200317 return max_f;
318
Rafael J. Wysocki193d25c2016-09-10 00:00:31 +0200319 sugov_iowait_boost(sg_cpu, &util, &max);
Rohit Gupta30249632017-02-02 18:39:07 -0800320 sugov_walt_adjust(sg_cpu, &util, &max);
Rafael J. Wysocki193d25c2016-09-10 00:00:31 +0200321
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200322 for_each_cpu(j, policy->cpus) {
323 struct sugov_cpu *j_sg_cpu;
324 unsigned long j_util, j_max;
325 s64 delta_ns;
326
Vikram Mulukutla857cffa2017-05-04 19:47:06 -0700327 if (j == sg_cpu->cpu)
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200328 continue;
329
330 j_sg_cpu = &per_cpu(sugov_cpu, j);
331 /*
332 * If the CPU utilization was last updated before the previous
333 * frequency update and the time elapsed between the last update
334 * of the CPU utilization and the last frequency update is long
335 * enough, don't take the CPU into account as it probably is
Rafael J. Wysocki193d25c2016-09-10 00:00:31 +0200336 * idle now (and clear iowait_boost for it).
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200337 */
338 delta_ns = last_freq_update_time - j_sg_cpu->last_update;
Saravana Kannane8450d42017-03-02 15:45:47 -0800339 if (delta_ns > sched_ravg_window) {
Rafael J. Wysocki193d25c2016-09-10 00:00:31 +0200340 j_sg_cpu->iowait_boost = 0;
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200341 continue;
Rafael J. Wysocki193d25c2016-09-10 00:00:31 +0200342 }
Rafael J. Wysockic4568722016-08-16 22:14:55 +0200343 if (j_sg_cpu->flags & SCHED_CPUFREQ_RT_DL)
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200344 return max_f;
345
Rafael J. Wysockic4568722016-08-16 22:14:55 +0200346 j_util = j_sg_cpu->util;
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200347 j_max = j_sg_cpu->max;
348 if (j_util * max > j_max * util) {
349 util = j_util;
350 max = j_max;
351 }
Rafael J. Wysocki193d25c2016-09-10 00:00:31 +0200352
353 sugov_iowait_boost(j_sg_cpu, &util, &max);
Rohit Gupta30249632017-02-02 18:39:07 -0800354 sugov_walt_adjust(j_sg_cpu, &util, &max);
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200355 }
356
Viresh Kumare74f7f12017-03-02 14:03:21 +0530357 return get_next_freq(sg_policy, util, max);
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200358}
359
360static void sugov_update_shared(struct update_util_data *hook, u64 time,
Rafael J. Wysockic4568722016-08-16 22:14:55 +0200361 unsigned int flags)
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200362{
363 struct sugov_cpu *sg_cpu = container_of(hook, struct sugov_cpu, update_util);
364 struct sugov_policy *sg_policy = sg_cpu->sg_policy;
Rohit Gupta30249632017-02-02 18:39:07 -0800365 unsigned long util, max, hs_util;
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200366 unsigned int next_f;
367
Vikram Mulukutla857cffa2017-05-04 19:47:06 -0700368 sugov_get_util(&util, &max, sg_cpu->cpu);
Rafael J. Wysockic4568722016-08-16 22:14:55 +0200369
Saravana Kannan76ef1712017-05-04 19:44:36 -0700370 flags &= ~SCHED_CPUFREQ_RT_DL;
371
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200372 raw_spin_lock(&sg_policy->update_lock);
373
Rohit Gupta30249632017-02-02 18:39:07 -0800374 if (sg_policy->max != max) {
Saravana Kannanaf541e12017-06-28 20:16:15 -0700375 sg_policy->max = max;
376 hs_util = freq_to_util(sg_policy,
377 sg_policy->tunables->hispeed_freq);
Rohit Gupta30249632017-02-02 18:39:07 -0800378 hs_util = mult_frac(hs_util, TARGET_LOAD, 100);
379 sg_policy->hispeed_util = hs_util;
Rohit Gupta30249632017-02-02 18:39:07 -0800380 }
381
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200382 sg_cpu->util = util;
383 sg_cpu->max = max;
Rafael J. Wysockic4568722016-08-16 22:14:55 +0200384 sg_cpu->flags = flags;
Rafael J. Wysocki193d25c2016-09-10 00:00:31 +0200385
386 sugov_set_iowait_boost(sg_cpu, time, flags);
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200387 sg_cpu->last_update = time;
388
Saravana Kannan0f34ee92017-06-28 21:44:14 -0700389 sugov_calc_avg_cap(sg_policy, sg_cpu->walt_load.ws,
390 sg_policy->policy->cur);
391
Saravana Kannan12a35ed2017-03-27 15:46:28 -0700392 trace_sugov_util_update(sg_cpu->cpu, sg_cpu->util, max,
393 sg_cpu->walt_load.nl,
394 sg_cpu->walt_load.pl, flags);
395
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200396 if (sugov_should_update_freq(sg_policy, time)) {
Rafael J. Wysockic4568722016-08-16 22:14:55 +0200397 next_f = sugov_next_freq_shared(sg_cpu, util, max, flags);
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200398 sugov_update_commit(sg_policy, time, next_f);
399 }
400
401 raw_spin_unlock(&sg_policy->update_lock);
402}
403
Viresh Kumara231c652016-11-15 13:53:22 +0530404static void sugov_work(struct kthread_work *work)
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200405{
406 struct sugov_policy *sg_policy = container_of(work, struct sugov_policy, work);
407
408 mutex_lock(&sg_policy->work_lock);
Saravana Kannan0f34ee92017-06-28 21:44:14 -0700409 raw_spin_lock(&sg_policy->update_lock);
410 sugov_track_cycles(sg_policy, sg_policy->policy->cur,
411 sched_ktime_clock());
412 raw_spin_unlock(&sg_policy->update_lock);
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200413 __cpufreq_driver_target(sg_policy->policy, sg_policy->next_freq,
414 CPUFREQ_RELATION_L);
415 mutex_unlock(&sg_policy->work_lock);
416
417 sg_policy->work_in_progress = false;
418}
419
420static void sugov_irq_work(struct irq_work *irq_work)
421{
422 struct sugov_policy *sg_policy;
423
424 sg_policy = container_of(irq_work, struct sugov_policy, irq_work);
Viresh Kumara231c652016-11-15 13:53:22 +0530425
426 /*
Viresh Kumar75526a22016-11-24 13:51:11 +0530427 * For RT and deadline tasks, the schedutil governor shoots the
428 * frequency to maximum. Special care must be taken to ensure that this
429 * kthread doesn't result in the same behavior.
Viresh Kumara231c652016-11-15 13:53:22 +0530430 *
431 * This is (mostly) guaranteed by the work_in_progress flag. The flag is
Viresh Kumar75526a22016-11-24 13:51:11 +0530432 * updated only at the end of the sugov_work() function and before that
433 * the schedutil governor rejects all other frequency scaling requests.
Viresh Kumara231c652016-11-15 13:53:22 +0530434 *
Viresh Kumar75526a22016-11-24 13:51:11 +0530435 * There is a very rare case though, where the RT thread yields right
Viresh Kumara231c652016-11-15 13:53:22 +0530436 * after the work_in_progress flag is cleared. The effects of that are
437 * neglected for now.
438 */
439 kthread_queue_work(&sg_policy->worker, &sg_policy->work);
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200440}
441
442/************************** sysfs interface ************************/
443
444static struct sugov_tunables *global_tunables;
445static DEFINE_MUTEX(global_tunables_lock);
446
447static inline struct sugov_tunables *to_sugov_tunables(struct gov_attr_set *attr_set)
448{
449 return container_of(attr_set, struct sugov_tunables, attr_set);
450}
451
452static ssize_t rate_limit_us_show(struct gov_attr_set *attr_set, char *buf)
453{
454 struct sugov_tunables *tunables = to_sugov_tunables(attr_set);
455
456 return sprintf(buf, "%u\n", tunables->rate_limit_us);
457}
458
459static ssize_t rate_limit_us_store(struct gov_attr_set *attr_set, const char *buf,
460 size_t count)
461{
462 struct sugov_tunables *tunables = to_sugov_tunables(attr_set);
463 struct sugov_policy *sg_policy;
464 unsigned int rate_limit_us;
465
466 if (kstrtouint(buf, 10, &rate_limit_us))
467 return -EINVAL;
468
469 tunables->rate_limit_us = rate_limit_us;
470
471 list_for_each_entry(sg_policy, &attr_set->policy_list, tunables_hook)
472 sg_policy->freq_update_delay_ns = rate_limit_us * NSEC_PER_USEC;
473
474 return count;
475}
476
Rohit Gupta30249632017-02-02 18:39:07 -0800477static ssize_t hispeed_freq_show(struct gov_attr_set *attr_set, char *buf)
478{
479 struct sugov_tunables *tunables = to_sugov_tunables(attr_set);
480
481 return sprintf(buf, "%u\n", tunables->hispeed_freq);
482}
483
484static ssize_t hispeed_freq_store(struct gov_attr_set *attr_set,
485 const char *buf, size_t count)
486{
487 struct sugov_tunables *tunables = to_sugov_tunables(attr_set);
488 unsigned int val;
489 struct sugov_policy *sg_policy;
490 unsigned long hs_util;
491
492 if (kstrtouint(buf, 10, &val))
493 return -EINVAL;
494
495 tunables->hispeed_freq = val;
496 list_for_each_entry(sg_policy, &attr_set->policy_list, tunables_hook) {
Saravana Kannanaf541e12017-06-28 20:16:15 -0700497 hs_util = freq_to_util(sg_policy,
498 sg_policy->tunables->hispeed_freq);
Rohit Gupta30249632017-02-02 18:39:07 -0800499 hs_util = mult_frac(hs_util, TARGET_LOAD, 100);
500 sg_policy->hispeed_util = hs_util;
501 }
502
503 return count;
504}
505
Saravana Kannand0a7c6b2017-05-23 17:26:32 -0700506static ssize_t pl_show(struct gov_attr_set *attr_set, char *buf)
507{
508 struct sugov_tunables *tunables = to_sugov_tunables(attr_set);
509
510 return sprintf(buf, "%u\n", tunables->pl);
511}
512
513static ssize_t pl_store(struct gov_attr_set *attr_set, const char *buf,
514 size_t count)
515{
516 struct sugov_tunables *tunables = to_sugov_tunables(attr_set);
517
518 if (kstrtobool(buf, &tunables->pl))
519 return -EINVAL;
520
521 return count;
522}
523
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200524static struct governor_attr rate_limit_us = __ATTR_RW(rate_limit_us);
Rohit Gupta30249632017-02-02 18:39:07 -0800525static struct governor_attr hispeed_freq = __ATTR_RW(hispeed_freq);
Saravana Kannand0a7c6b2017-05-23 17:26:32 -0700526static struct governor_attr pl = __ATTR_RW(pl);
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200527
528static struct attribute *sugov_attributes[] = {
529 &rate_limit_us.attr,
Rohit Gupta30249632017-02-02 18:39:07 -0800530 &hispeed_freq.attr,
Saravana Kannand0a7c6b2017-05-23 17:26:32 -0700531 &pl.attr,
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200532 NULL
533};
534
535static struct kobj_type sugov_tunables_ktype = {
536 .default_attrs = sugov_attributes,
537 .sysfs_ops = &governor_sysfs_ops,
538};
539
540/********************** cpufreq governor interface *********************/
541
542static struct cpufreq_governor schedutil_gov;
543
544static struct sugov_policy *sugov_policy_alloc(struct cpufreq_policy *policy)
545{
546 struct sugov_policy *sg_policy;
547
548 sg_policy = kzalloc(sizeof(*sg_policy), GFP_KERNEL);
549 if (!sg_policy)
550 return NULL;
551
552 sg_policy->policy = policy;
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200553 raw_spin_lock_init(&sg_policy->update_lock);
554 return sg_policy;
555}
556
557static void sugov_policy_free(struct sugov_policy *sg_policy)
558{
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200559 kfree(sg_policy);
560}
561
Viresh Kumara231c652016-11-15 13:53:22 +0530562static int sugov_kthread_create(struct sugov_policy *sg_policy)
563{
564 struct task_struct *thread;
565 struct sched_param param = { .sched_priority = MAX_USER_RT_PRIO / 2 };
566 struct cpufreq_policy *policy = sg_policy->policy;
567 int ret;
568
569 /* kthread only required for slow path */
570 if (policy->fast_switch_enabled)
571 return 0;
572
573 kthread_init_work(&sg_policy->work, sugov_work);
574 kthread_init_worker(&sg_policy->worker);
575 thread = kthread_create(kthread_worker_fn, &sg_policy->worker,
576 "sugov:%d",
577 cpumask_first(policy->related_cpus));
578 if (IS_ERR(thread)) {
579 pr_err("failed to create sugov thread: %ld\n", PTR_ERR(thread));
580 return PTR_ERR(thread);
581 }
582
583 ret = sched_setscheduler_nocheck(thread, SCHED_FIFO, &param);
584 if (ret) {
585 kthread_stop(thread);
586 pr_warn("%s: failed to set SCHED_FIFO\n", __func__);
587 return ret;
588 }
589
590 sg_policy->thread = thread;
591 kthread_bind_mask(thread, policy->related_cpus);
Viresh Kumar0ced0be2016-11-15 13:53:23 +0530592 init_irq_work(&sg_policy->irq_work, sugov_irq_work);
593 mutex_init(&sg_policy->work_lock);
594
Viresh Kumara231c652016-11-15 13:53:22 +0530595 wake_up_process(thread);
596
597 return 0;
598}
599
600static void sugov_kthread_stop(struct sugov_policy *sg_policy)
601{
602 /* kthread only required for slow path */
603 if (sg_policy->policy->fast_switch_enabled)
604 return;
605
606 kthread_flush_worker(&sg_policy->worker);
607 kthread_stop(sg_policy->thread);
Viresh Kumar0ced0be2016-11-15 13:53:23 +0530608 mutex_destroy(&sg_policy->work_lock);
Viresh Kumara231c652016-11-15 13:53:22 +0530609}
610
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200611static struct sugov_tunables *sugov_tunables_alloc(struct sugov_policy *sg_policy)
612{
613 struct sugov_tunables *tunables;
614
615 tunables = kzalloc(sizeof(*tunables), GFP_KERNEL);
616 if (tunables) {
617 gov_attr_set_init(&tunables->attr_set, &sg_policy->tunables_hook);
618 if (!have_governor_per_policy())
619 global_tunables = tunables;
620 }
621 return tunables;
622}
623
624static void sugov_tunables_free(struct sugov_tunables *tunables)
625{
626 if (!have_governor_per_policy())
627 global_tunables = NULL;
628
629 kfree(tunables);
630}
631
632static int sugov_init(struct cpufreq_policy *policy)
633{
634 struct sugov_policy *sg_policy;
635 struct sugov_tunables *tunables;
636 unsigned int lat;
637 int ret = 0;
638
639 /* State should be equivalent to EXIT */
640 if (policy->governor_data)
641 return -EBUSY;
642
Viresh Kumar6d5551b2016-11-15 13:53:21 +0530643 cpufreq_enable_fast_switch(policy);
644
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200645 sg_policy = sugov_policy_alloc(policy);
Viresh Kumar6d5551b2016-11-15 13:53:21 +0530646 if (!sg_policy) {
647 ret = -ENOMEM;
648 goto disable_fast_switch;
649 }
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200650
Viresh Kumara231c652016-11-15 13:53:22 +0530651 ret = sugov_kthread_create(sg_policy);
652 if (ret)
653 goto free_sg_policy;
654
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200655 mutex_lock(&global_tunables_lock);
656
657 if (global_tunables) {
658 if (WARN_ON(have_governor_per_policy())) {
659 ret = -EINVAL;
Viresh Kumara231c652016-11-15 13:53:22 +0530660 goto stop_kthread;
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200661 }
662 policy->governor_data = sg_policy;
663 sg_policy->tunables = global_tunables;
664
665 gov_attr_set_get(&global_tunables->attr_set, &sg_policy->tunables_hook);
666 goto out;
667 }
668
669 tunables = sugov_tunables_alloc(sg_policy);
670 if (!tunables) {
671 ret = -ENOMEM;
Viresh Kumara231c652016-11-15 13:53:22 +0530672 goto stop_kthread;
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200673 }
674
675 tunables->rate_limit_us = LATENCY_MULTIPLIER;
Rohit Gupta30249632017-02-02 18:39:07 -0800676 tunables->hispeed_freq = 0;
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200677 lat = policy->cpuinfo.transition_latency / NSEC_PER_USEC;
678 if (lat)
679 tunables->rate_limit_us *= lat;
680
681 policy->governor_data = sg_policy;
682 sg_policy->tunables = tunables;
683
684 ret = kobject_init_and_add(&tunables->attr_set.kobj, &sugov_tunables_ktype,
685 get_governor_parent_kobj(policy), "%s",
686 schedutil_gov.name);
687 if (ret)
688 goto fail;
689
Viresh Kumarb5b11602016-11-15 13:53:20 +0530690out:
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200691 mutex_unlock(&global_tunables_lock);
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200692 return 0;
693
Viresh Kumarb5b11602016-11-15 13:53:20 +0530694fail:
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200695 policy->governor_data = NULL;
696 sugov_tunables_free(tunables);
697
Viresh Kumara231c652016-11-15 13:53:22 +0530698stop_kthread:
699 sugov_kthread_stop(sg_policy);
700
Viresh Kumarb5b11602016-11-15 13:53:20 +0530701free_sg_policy:
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200702 mutex_unlock(&global_tunables_lock);
703
704 sugov_policy_free(sg_policy);
Viresh Kumar6d5551b2016-11-15 13:53:21 +0530705
706disable_fast_switch:
707 cpufreq_disable_fast_switch(policy);
708
Viresh Kumar87ecf322016-05-18 17:55:28 +0530709 pr_err("initialization failed (error %d)\n", ret);
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200710 return ret;
711}
712
Rafael J. Wysocki48f5adc2016-06-02 23:24:15 +0200713static void sugov_exit(struct cpufreq_policy *policy)
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200714{
715 struct sugov_policy *sg_policy = policy->governor_data;
716 struct sugov_tunables *tunables = sg_policy->tunables;
717 unsigned int count;
718
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200719 mutex_lock(&global_tunables_lock);
720
721 count = gov_attr_set_put(&tunables->attr_set, &sg_policy->tunables_hook);
722 policy->governor_data = NULL;
723 if (!count)
724 sugov_tunables_free(tunables);
725
726 mutex_unlock(&global_tunables_lock);
727
Viresh Kumara231c652016-11-15 13:53:22 +0530728 sugov_kthread_stop(sg_policy);
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200729 sugov_policy_free(sg_policy);
Viresh Kumar6d5551b2016-11-15 13:53:21 +0530730 cpufreq_disable_fast_switch(policy);
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200731}
732
733static int sugov_start(struct cpufreq_policy *policy)
734{
735 struct sugov_policy *sg_policy = policy->governor_data;
736 unsigned int cpu;
737
738 sg_policy->freq_update_delay_ns = sg_policy->tunables->rate_limit_us * NSEC_PER_USEC;
739 sg_policy->last_freq_update_time = 0;
740 sg_policy->next_freq = UINT_MAX;
741 sg_policy->work_in_progress = false;
742 sg_policy->need_freq_update = false;
Viresh Kumar55a6d462017-03-02 14:03:20 +0530743 sg_policy->cached_raw_freq = 0;
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200744
745 for_each_cpu(cpu, policy->cpus) {
746 struct sugov_cpu *sg_cpu = &per_cpu(sugov_cpu, cpu);
747
Rafael J. Wysocki7922ae42017-03-19 14:30:02 +0100748 memset(sg_cpu, 0, sizeof(*sg_cpu));
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200749 sg_cpu->sg_policy = sg_policy;
Vikram Mulukutla857cffa2017-05-04 19:47:06 -0700750 sg_cpu->cpu = cpu;
Rafael J. Wysocki7922ae42017-03-19 14:30:02 +0100751 sg_cpu->flags = SCHED_CPUFREQ_RT;
752 sg_cpu->iowait_boost_max = policy->cpuinfo.max_freq;
753 cpufreq_add_update_util_hook(cpu, &sg_cpu->update_util,
754 policy_is_shared(policy) ?
755 sugov_update_shared :
756 sugov_update_single);
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200757 }
758 return 0;
759}
760
Rafael J. Wysocki48f5adc2016-06-02 23:24:15 +0200761static void sugov_stop(struct cpufreq_policy *policy)
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200762{
763 struct sugov_policy *sg_policy = policy->governor_data;
764 unsigned int cpu;
765
766 for_each_cpu(cpu, policy->cpus)
767 cpufreq_remove_update_util_hook(cpu);
768
769 synchronize_sched();
770
Viresh Kumar0ced0be2016-11-15 13:53:23 +0530771 if (!policy->fast_switch_enabled) {
772 irq_work_sync(&sg_policy->irq_work);
773 kthread_cancel_work_sync(&sg_policy->work);
774 }
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200775}
776
Rafael J. Wysocki48f5adc2016-06-02 23:24:15 +0200777static void sugov_limits(struct cpufreq_policy *policy)
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200778{
779 struct sugov_policy *sg_policy = policy->governor_data;
780
781 if (!policy->fast_switch_enabled) {
782 mutex_lock(&sg_policy->work_lock);
Saravana Kannan0f34ee92017-06-28 21:44:14 -0700783 raw_spin_lock(&sg_policy->update_lock);
784 sugov_track_cycles(sg_policy, sg_policy->policy->cur,
785 sched_ktime_clock());
786 raw_spin_unlock(&sg_policy->update_lock);
Viresh Kumar73d427c2016-05-18 17:55:31 +0530787 cpufreq_policy_apply_limits(policy);
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200788 mutex_unlock(&sg_policy->work_lock);
789 }
790
791 sg_policy->need_freq_update = true;
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200792}
793
794static struct cpufreq_governor schedutil_gov = {
795 .name = "schedutil",
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200796 .owner = THIS_MODULE,
Rafael J. Wysocki48f5adc2016-06-02 23:24:15 +0200797 .init = sugov_init,
798 .exit = sugov_exit,
799 .start = sugov_start,
800 .stop = sugov_stop,
801 .limits = sugov_limits,
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200802};
803
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200804#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL
805struct cpufreq_governor *cpufreq_default_governor(void)
806{
807 return &schedutil_gov;
808}
Rafael J. Wysockib1d09762016-04-02 01:09:12 +0200809#endif
Rafael J. Wysockic4568722016-08-16 22:14:55 +0200810
811static int __init sugov_register(void)
812{
813 return cpufreq_register_governor(&schedutil_gov);
814}
815fs_initcall(sugov_register);