ARM: dts: rk3288: support AP6335 bt for rk3288-firefly
[firefly-linux-kernel-4.4.55.git] / kernel / sched / tune.c
1 #include <linux/cgroup.h>
2 #include <linux/err.h>
3 #include <linux/kernel.h>
4 #include <linux/percpu.h>
5 #include <linux/printk.h>
6 #include <linux/reciprocal_div.h>
7 #include <linux/rcupdate.h>
8 #include <linux/slab.h>
9
10 #include <trace/events/sched.h>
11
12 #include "sched.h"
13
14 unsigned int sysctl_sched_cfs_boost __read_mostly;
15
16 /*
17  * System energy normalization constants
18  */
19 static struct target_nrg {
20         unsigned long min_power;
21         unsigned long max_power;
22         struct reciprocal_value rdiv;
23 } schedtune_target_nrg;
24
25 /* Performance Boost region (B) threshold params */
26 static int perf_boost_idx;
27
28 /* Performance Constraint region (C) threshold params */
29 static int perf_constrain_idx;
30
31 /**
32  * Performance-Energy (P-E) Space thresholds constants
33  */
34 struct threshold_params {
35         int nrg_gain;
36         int cap_gain;
37 };
38
39 /*
40  * System specific P-E space thresholds constants
41  */
42 static struct threshold_params
43 threshold_gains[] = {
44         { 0, 4 }, /* >=  0% */
45         { 0, 4 }, /* >= 10% */
46         { 1, 4 }, /* >= 20% */
47         { 2, 4 }, /* >= 30% */
48         { 3, 4 }, /* >= 40% */
49         { 4, 3 }, /* >= 50% */
50         { 4, 2 }, /* >= 60% */
51         { 4, 1 }, /* >= 70% */
52         { 4, 0 }, /* >= 80% */
53         { 4, 0 }  /* >= 90% */
54 };
55
56 static int
57 __schedtune_accept_deltas(int nrg_delta, int cap_delta,
58                           int perf_boost_idx, int perf_constrain_idx)
59 {
60         int payoff = -INT_MAX;
61
62         /* Performance Boost (B) region */
63         if (nrg_delta > 0 && cap_delta > 0) {
64                 /*
65                  * Evaluate "Performance Boost" vs "Energy Increase"
66                  * payoff criteria:
67                  *    cap_delta / nrg_delta < cap_gain / nrg_gain
68                  * which is:
69                  *    nrg_delta * cap_gain > cap_delta * nrg_gain
70                  */
71                 payoff  = nrg_delta * threshold_gains[perf_boost_idx].cap_gain;
72                 payoff -= cap_delta * threshold_gains[perf_boost_idx].nrg_gain;
73                 return payoff;
74         }
75
76         /* Performance Constraint (C) region */
77         if (nrg_delta < 0 && cap_delta < 0) {
78                 /*
79                  * Evaluate "Performance Boost" vs "Energy Increase"
80                  * payoff criteria:
81                  *    cap_delta / nrg_delta > cap_gain / nrg_gain
82                  * which is:
83                  *    cap_delta * nrg_gain > nrg_delta * cap_gain
84                  */
85                 payoff  = cap_delta * threshold_gains[perf_constrain_idx].nrg_gain;
86                 payoff -= nrg_delta * threshold_gains[perf_constrain_idx].cap_gain;
87                 return payoff;
88         }
89
90         /* Default: reject schedule candidate */
91         return payoff;
92 }
93
94 #ifdef CONFIG_CGROUP_SCHEDTUNE
95
96 /*
97  * EAS scheduler tunables for task groups.
98  */
99
100 /* SchdTune tunables for a group of tasks */
101 struct schedtune {
102         /* SchedTune CGroup subsystem */
103         struct cgroup_subsys_state css;
104
105         /* Boost group allocated ID */
106         int idx;
107
108         /* Boost value for tasks on that SchedTune CGroup */
109         int boost;
110
111         /* Performance Boost (B) region threshold params */
112         int perf_boost_idx;
113
114         /* Performance Constraint (C) region threshold params */
115         int perf_constrain_idx;
116 };
117
118 static inline struct schedtune *css_st(struct cgroup_subsys_state *css)
119 {
120         return css ? container_of(css, struct schedtune, css) : NULL;
121 }
122
123 static inline struct schedtune *task_schedtune(struct task_struct *tsk)
124 {
125         return css_st(task_css(tsk, schedtune_cgrp_id));
126 }
127
128 static inline struct schedtune *parent_st(struct schedtune *st)
129 {
130         return css_st(st->css.parent);
131 }
132
133 /*
134  * SchedTune root control group
135  * The root control group is used to defined a system-wide boosting tuning,
136  * which is applied to all tasks in the system.
137  * Task specific boost tuning could be specified by creating and
138  * configuring a child control group under the root one.
139  * By default, system-wide boosting is disabled, i.e. no boosting is applied
140  * to tasks which are not into a child control group.
141  */
142 static struct schedtune
143 root_schedtune = {
144         .boost  = 0,
145         .perf_boost_idx = 0,
146         .perf_constrain_idx = 0,
147 };
148
149 int
150 schedtune_accept_deltas(int nrg_delta, int cap_delta,
151                         struct task_struct *task)
152 {
153         struct schedtune *ct;
154         int perf_boost_idx;
155         int perf_constrain_idx;
156
157         /* Optimal (O) region */
158         if (nrg_delta < 0 && cap_delta > 0)
159                 return INT_MAX;
160
161         /* Suboptimal (S) region */
162         if (nrg_delta > 0 && cap_delta < 0)
163                 return -INT_MAX;
164
165         /* Get task specific perf Boost/Constraints indexes */
166         rcu_read_lock();
167         ct = task_schedtune(task);
168         perf_boost_idx = ct->perf_boost_idx;
169         perf_constrain_idx = ct->perf_constrain_idx;
170         rcu_read_unlock();
171
172         return __schedtune_accept_deltas(nrg_delta, cap_delta,
173                         perf_boost_idx, perf_constrain_idx);
174 }
175
176 /*
177  * Maximum number of boost groups to support
178  * When per-task boosting is used we still allow only limited number of
179  * boost groups for two main reasons:
180  * 1. on a real system we usually have only few classes of workloads which
181  *    make sense to boost with different values (e.g. background vs foreground
182  *    tasks, interactive vs low-priority tasks)
183  * 2. a limited number allows for a simpler and more memory/time efficient
184  *    implementation especially for the computation of the per-CPU boost
185  *    value
186  */
187 #define BOOSTGROUPS_COUNT 4
188
189 /* Array of configured boostgroups */
190 static struct schedtune *allocated_group[BOOSTGROUPS_COUNT] = {
191         &root_schedtune,
192         NULL,
193 };
194
195 /* SchedTune boost groups
196  * Keep track of all the boost groups which impact on CPU, for example when a
197  * CPU has two RUNNABLE tasks belonging to two different boost groups and thus
198  * likely with different boost values.
199  * Since on each system we expect only a limited number of boost groups, here
200  * we use a simple array to keep track of the metrics required to compute the
201  * maximum per-CPU boosting value.
202  */
203 struct boost_groups {
204         /* Maximum boost value for all RUNNABLE tasks on a CPU */
205         unsigned boost_max;
206         struct {
207                 /* The boost for tasks on that boost group */
208                 unsigned boost;
209                 /* Count of RUNNABLE tasks on that boost group */
210                 unsigned tasks;
211         } group[BOOSTGROUPS_COUNT];
212 };
213
214 /* Boost groups affecting each CPU in the system */
215 DEFINE_PER_CPU(struct boost_groups, cpu_boost_groups);
216
217 static void
218 schedtune_cpu_update(int cpu)
219 {
220         struct boost_groups *bg;
221         unsigned boost_max;
222         int idx;
223
224         bg = &per_cpu(cpu_boost_groups, cpu);
225
226         /* The root boost group is always active */
227         boost_max = bg->group[0].boost;
228         for (idx = 1; idx < BOOSTGROUPS_COUNT; ++idx) {
229                 /*
230                  * A boost group affects a CPU only if it has
231                  * RUNNABLE tasks on that CPU
232                  */
233                 if (bg->group[idx].tasks == 0)
234                         continue;
235                 boost_max = max(boost_max, bg->group[idx].boost);
236         }
237
238         bg->boost_max = boost_max;
239 }
240
241 static int
242 schedtune_boostgroup_update(int idx, int boost)
243 {
244         struct boost_groups *bg;
245         int cur_boost_max;
246         int old_boost;
247         int cpu;
248
249         /* Update per CPU boost groups */
250         for_each_possible_cpu(cpu) {
251                 bg = &per_cpu(cpu_boost_groups, cpu);
252
253                 /*
254                  * Keep track of current boost values to compute the per CPU
255                  * maximum only when it has been affected by the new value of
256                  * the updated boost group
257                  */
258                 cur_boost_max = bg->boost_max;
259                 old_boost = bg->group[idx].boost;
260
261                 /* Update the boost value of this boost group */
262                 bg->group[idx].boost = boost;
263
264                 /* Check if this update increase current max */
265                 if (boost > cur_boost_max && bg->group[idx].tasks) {
266                         bg->boost_max = boost;
267                         trace_sched_tune_boostgroup_update(cpu, 1, bg->boost_max);
268                         continue;
269                 }
270
271                 /* Check if this update has decreased current max */
272                 if (cur_boost_max == old_boost && old_boost > boost) {
273                         schedtune_cpu_update(cpu);
274                         trace_sched_tune_boostgroup_update(cpu, -1, bg->boost_max);
275                         continue;
276                 }
277
278                 trace_sched_tune_boostgroup_update(cpu, 0, bg->boost_max);
279         }
280
281         return 0;
282 }
283
284 static inline void
285 schedtune_tasks_update(struct task_struct *p, int cpu, int idx, int task_count)
286 {
287         struct boost_groups *bg;
288         int tasks;
289
290         bg = &per_cpu(cpu_boost_groups, cpu);
291
292         /* Update boosted tasks count while avoiding to make it negative */
293         if (task_count < 0 && bg->group[idx].tasks <= -task_count)
294                 bg->group[idx].tasks = 0;
295         else
296                 bg->group[idx].tasks += task_count;
297
298         /* Boost group activation or deactivation on that RQ */
299         tasks = bg->group[idx].tasks;
300         if (tasks == 1 || tasks == 0)
301                 schedtune_cpu_update(cpu);
302
303         trace_sched_tune_tasks_update(p, cpu, tasks, idx,
304                         bg->group[idx].boost, bg->boost_max);
305
306 }
307
308 /*
309  * NOTE: This function must be called while holding the lock on the CPU RQ
310  */
311 void schedtune_enqueue_task(struct task_struct *p, int cpu)
312 {
313         struct schedtune *st;
314         int idx;
315
316         /*
317          * When a task is marked PF_EXITING by do_exit() it's going to be
318          * dequeued and enqueued multiple times in the exit path.
319          * Thus we avoid any further update, since we do not want to change
320          * CPU boosting while the task is exiting.
321          */
322         if (p->flags & PF_EXITING)
323                 return;
324
325         /* Get task boost group */
326         rcu_read_lock();
327         st = task_schedtune(p);
328         idx = st->idx;
329         rcu_read_unlock();
330
331         schedtune_tasks_update(p, cpu, idx, 1);
332 }
333
334 /*
335  * NOTE: This function must be called while holding the lock on the CPU RQ
336  */
337 void schedtune_dequeue_task(struct task_struct *p, int cpu)
338 {
339         struct schedtune *st;
340         int idx;
341
342         /*
343          * When a task is marked PF_EXITING by do_exit() it's going to be
344          * dequeued and enqueued multiple times in the exit path.
345          * Thus we avoid any further update, since we do not want to change
346          * CPU boosting while the task is exiting.
347          * The last dequeue will be done by cgroup exit() callback.
348          */
349         if (p->flags & PF_EXITING)
350                 return;
351
352         /* Get task boost group */
353         rcu_read_lock();
354         st = task_schedtune(p);
355         idx = st->idx;
356         rcu_read_unlock();
357
358         schedtune_tasks_update(p, cpu, idx, -1);
359 }
360
361 int schedtune_cpu_boost(int cpu)
362 {
363         struct boost_groups *bg;
364
365         bg = &per_cpu(cpu_boost_groups, cpu);
366         return bg->boost_max;
367 }
368
369 int schedtune_task_boost(struct task_struct *p)
370 {
371         struct schedtune *st;
372         int task_boost;
373
374         /* Get task boost value */
375         rcu_read_lock();
376         st = task_schedtune(p);
377         task_boost = st->boost;
378         rcu_read_unlock();
379
380         return task_boost;
381 }
382
383 static u64
384 boost_read(struct cgroup_subsys_state *css, struct cftype *cft)
385 {
386         struct schedtune *st = css_st(css);
387
388         return st->boost;
389 }
390
391 static int
392 boost_write(struct cgroup_subsys_state *css, struct cftype *cft,
393             u64 boost)
394 {
395         struct schedtune *st = css_st(css);
396
397         if (boost < 0 || boost > 100)
398                 return -EINVAL;
399
400         st->boost = boost;
401         if (css == &root_schedtune.css)
402                 sysctl_sched_cfs_boost = boost;
403
404         /* Update CPU boost */
405         schedtune_boostgroup_update(st->idx, st->boost);
406
407         trace_sched_tune_config(st->boost);
408
409         return 0;
410 }
411
412 static struct cftype files[] = {
413         {
414                 .name = "boost",
415                 .read_u64 = boost_read,
416                 .write_u64 = boost_write,
417         },
418         { }     /* terminate */
419 };
420
421 static int
422 schedtune_boostgroup_init(struct schedtune *st)
423 {
424         struct boost_groups *bg;
425         int cpu;
426
427         /* Keep track of allocated boost groups */
428         allocated_group[st->idx] = st;
429
430         /* Initialize the per CPU boost groups */
431         for_each_possible_cpu(cpu) {
432                 bg = &per_cpu(cpu_boost_groups, cpu);
433                 bg->group[st->idx].boost = 0;
434                 bg->group[st->idx].tasks = 0;
435         }
436
437         return 0;
438 }
439
440 static int
441 schedtune_init(void)
442 {
443         struct boost_groups *bg;
444         int cpu;
445
446         /* Initialize the per CPU boost groups */
447         for_each_possible_cpu(cpu) {
448                 bg = &per_cpu(cpu_boost_groups, cpu);
449                 memset(bg, 0, sizeof(struct boost_groups));
450         }
451
452         pr_info("  schedtune configured to support %d boost groups\n",
453                 BOOSTGROUPS_COUNT);
454         return 0;
455 }
456
457 static struct cgroup_subsys_state *
458 schedtune_css_alloc(struct cgroup_subsys_state *parent_css)
459 {
460         struct schedtune *st;
461         int idx;
462
463         if (!parent_css) {
464                 schedtune_init();
465                 return &root_schedtune.css;
466         }
467
468         /* Allow only single level hierachies */
469         if (parent_css != &root_schedtune.css) {
470                 pr_err("Nested SchedTune boosting groups not allowed\n");
471                 return ERR_PTR(-ENOMEM);
472         }
473
474         /* Allow only a limited number of boosting groups */
475         for (idx = 1; idx < BOOSTGROUPS_COUNT; ++idx)
476                 if (!allocated_group[idx])
477                         break;
478         if (idx == BOOSTGROUPS_COUNT) {
479                 pr_err("Trying to create more than %d SchedTune boosting groups\n",
480                        BOOSTGROUPS_COUNT);
481                 return ERR_PTR(-ENOSPC);
482         }
483
484         st = kzalloc(sizeof(*st), GFP_KERNEL);
485         if (!st)
486                 goto out;
487
488         /* Initialize per CPUs boost group support */
489         st->idx = idx;
490         if (schedtune_boostgroup_init(st))
491                 goto release;
492
493         return &st->css;
494
495 release:
496         kfree(st);
497 out:
498         return ERR_PTR(-ENOMEM);
499 }
500
501 static void
502 schedtune_boostgroup_release(struct schedtune *st)
503 {
504         /* Reset this boost group */
505         schedtune_boostgroup_update(st->idx, 0);
506
507         /* Keep track of allocated boost groups */
508         allocated_group[st->idx] = NULL;
509 }
510
511 static void
512 schedtune_css_free(struct cgroup_subsys_state *css)
513 {
514         struct schedtune *st = css_st(css);
515
516         schedtune_boostgroup_release(st);
517         kfree(st);
518 }
519
520 struct cgroup_subsys schedtune_cgrp_subsys = {
521         .css_alloc      = schedtune_css_alloc,
522         .css_free       = schedtune_css_free,
523         .legacy_cftypes = files,
524         .early_init     = 1,
525 };
526
527 #else /* CONFIG_CGROUP_SCHEDTUNE */
528
529 int
530 schedtune_accept_deltas(int nrg_delta, int cap_delta,
531                         struct task_struct *task)
532 {
533         /* Optimal (O) region */
534         if (nrg_delta < 0 && cap_delta > 0)
535                 return INT_MAX;
536
537         /* Suboptimal (S) region */
538         if (nrg_delta > 0 && cap_delta < 0)
539                 return -INT_MAX;
540
541         return __schedtune_accept_deltas(nrg_delta, cap_delta,
542                         perf_boost_idx, perf_constrain_idx);
543 }
544
545 #endif /* CONFIG_CGROUP_SCHEDTUNE */
546
547 int
548 sysctl_sched_cfs_boost_handler(struct ctl_table *table, int write,
549                                void __user *buffer, size_t *lenp,
550                                loff_t *ppos)
551 {
552         int ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
553
554         if (ret || !write)
555                 return ret;
556
557         /* Performance Boost (B) region threshold params */
558         perf_boost_idx  = sysctl_sched_cfs_boost;
559         perf_boost_idx /= 10;
560
561         /* Performance Constraint (C) region threshold params */
562         perf_constrain_idx  = 100 - sysctl_sched_cfs_boost;
563         perf_constrain_idx /= 10;
564
565         return 0;
566 }
567
568 /*
569  * System energy normalization
570  * Returns the normalized value, in the range [0..SCHED_LOAD_SCALE],
571  * corresponding to the specified energy variation.
572  */
573 int
574 schedtune_normalize_energy(int energy_diff)
575 {
576         u32 normalized_nrg;
577         int max_delta;
578
579 #ifdef CONFIG_SCHED_DEBUG
580         /* Check for boundaries */
581         max_delta  = schedtune_target_nrg.max_power;
582         max_delta -= schedtune_target_nrg.min_power;
583         WARN_ON(abs(energy_diff) >= max_delta);
584 #endif
585
586         /* Do scaling using positive numbers to increase the range */
587         normalized_nrg = (energy_diff < 0) ? -energy_diff : energy_diff;
588
589         /* Scale by energy magnitude */
590         normalized_nrg <<= SCHED_LOAD_SHIFT;
591
592         /* Normalize on max energy for target platform */
593         normalized_nrg = reciprocal_divide(
594                         normalized_nrg, schedtune_target_nrg.rdiv);
595
596         return (energy_diff < 0) ? -normalized_nrg : normalized_nrg;
597 }
598
599 #ifdef CONFIG_SCHED_DEBUG
600 static void
601 schedtune_test_nrg(unsigned long delta_pwr)
602 {
603         unsigned long test_delta_pwr;
604         unsigned long test_norm_pwr;
605         int idx;
606
607         /*
608          * Check normalization constants using some constant system
609          * energy values
610          */
611         pr_info("schedtune: verify normalization constants...\n");
612         for (idx = 0; idx < 6; ++idx) {
613                 test_delta_pwr = delta_pwr >> idx;
614
615                 /* Normalize on max energy for target platform */
616                 test_norm_pwr = reciprocal_divide(
617                                         test_delta_pwr << SCHED_LOAD_SHIFT,
618                                         schedtune_target_nrg.rdiv);
619
620                 pr_info("schedtune: max_pwr/2^%d: %4lu => norm_pwr: %5lu\n",
621                         idx, test_delta_pwr, test_norm_pwr);
622         }
623 }
624 #else
625 #define schedtune_test_nrg(delta_pwr)
626 #endif
627
628 /*
629  * Compute the min/max power consumption of a cluster and all its CPUs
630  */
631 static void
632 schedtune_add_cluster_nrg(
633                 struct sched_domain *sd,
634                 struct sched_group *sg,
635                 struct target_nrg *ste)
636 {
637         struct sched_domain *sd2;
638         struct sched_group *sg2;
639
640         struct cpumask *cluster_cpus;
641         char str[32];
642
643         unsigned long min_pwr;
644         unsigned long max_pwr;
645         int cpu;
646
647         /* Get Cluster energy using EM data for the first CPU */
648         cluster_cpus = sched_group_cpus(sg);
649         snprintf(str, 32, "CLUSTER[%*pbl]",
650                  cpumask_pr_args(cluster_cpus));
651
652         min_pwr = sg->sge->idle_states[sg->sge->nr_idle_states - 1].power;
653         max_pwr = sg->sge->cap_states[sg->sge->nr_cap_states - 1].power;
654         pr_info("schedtune: %-17s min_pwr: %5lu max_pwr: %5lu\n",
655                 str, min_pwr, max_pwr);
656
657         /*
658          * Keep track of this cluster's energy in the computation of the
659          * overall system energy
660          */
661         ste->min_power += min_pwr;
662         ste->max_power += max_pwr;
663
664         /* Get CPU energy using EM data for each CPU in the group */
665         for_each_cpu(cpu, cluster_cpus) {
666                 /* Get a SD view for the specific CPU */
667                 for_each_domain(cpu, sd2) {
668                         /* Get the CPU group */
669                         sg2 = sd2->groups;
670                         min_pwr = sg2->sge->idle_states[sg2->sge->nr_idle_states - 1].power;
671                         max_pwr = sg2->sge->cap_states[sg2->sge->nr_cap_states - 1].power;
672
673                         ste->min_power += min_pwr;
674                         ste->max_power += max_pwr;
675
676                         snprintf(str, 32, "CPU[%d]", cpu);
677                         pr_info("schedtune: %-17s min_pwr: %5lu max_pwr: %5lu\n",
678                                 str, min_pwr, max_pwr);
679
680                         /*
681                          * Assume we have EM data only at the CPU and
682                          * the upper CLUSTER level
683                          */
684                         BUG_ON(!cpumask_equal(
685                                 sched_group_cpus(sg),
686                                 sched_group_cpus(sd2->parent->groups)
687                                 ));
688                         break;
689                 }
690         }
691 }
692
693 /*
694  * Initialize the constants required to compute normalized energy.
695  * The values of these constants depends on the EM data for the specific
696  * target system and topology.
697  * Thus, this function is expected to be called by the code
698  * that bind the EM to the topology information.
699  */
700 static int
701 schedtune_init_late(void)
702 {
703         struct target_nrg *ste = &schedtune_target_nrg;
704         unsigned long delta_pwr = 0;
705         struct sched_domain *sd;
706         struct sched_group *sg;
707
708         pr_info("schedtune: init normalization constants...\n");
709         ste->max_power = 0;
710         ste->min_power = 0;
711
712         rcu_read_lock();
713
714         /*
715          * When EAS is in use, we always have a pointer to the highest SD
716          * which provides EM data.
717          */
718         sd = rcu_dereference(per_cpu(sd_ea, cpumask_first(cpu_online_mask)));
719         if (!sd) {
720                 pr_info("schedtune: no energy model data\n");
721                 goto nodata;
722         }
723
724         sg = sd->groups;
725         do {
726                 schedtune_add_cluster_nrg(sd, sg, ste);
727         } while (sg = sg->next, sg != sd->groups);
728
729         rcu_read_unlock();
730
731         pr_info("schedtune: %-17s min_pwr: %5lu max_pwr: %5lu\n",
732                 "SYSTEM", ste->min_power, ste->max_power);
733
734         /* Compute normalization constants */
735         delta_pwr = ste->max_power - ste->min_power;
736         ste->rdiv = reciprocal_value(delta_pwr);
737         pr_info("schedtune: using normalization constants mul: %u sh1: %u sh2: %u\n",
738                 ste->rdiv.m, ste->rdiv.sh1, ste->rdiv.sh2);
739
740         schedtune_test_nrg(delta_pwr);
741         return 0;
742
743 nodata:
744         rcu_read_unlock();
745         return -EINVAL;
746 }
747 late_initcall(schedtune_init_late);
748