4 * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the License);
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
26 * pass_step_governor - Check cpu state and determine the amount of resource
28 * @stats: structure for getting cpu frequency state from kerncel
30 * This function check periodically current following state of system
31 * and then determine whether pass level up or down according to pass
32 * policy with gathered data.
33 * - current cpu frequency
34 * - the number of nr_running
35 * - the number of busy_cpu
37 int pass_step_governor(struct pass_policy *policy)
39 struct pass_table *table = policy->pass_table;
40 struct pass_cpu_stats *cpu_stats = policy->pass_cpu_stats;
41 int up_threshold = policy->up_threshold;
42 int down_threshold = policy->down_threshold;
44 int level = policy->curr_level;
57 static int64_t last_time = 0;
59 for (i = 0; i < policy->num_pass_cpu_stats; i++) {
60 time = cpu_stats[i].time;
61 freq = cpu_stats[i].freq;
62 nr_running = cpu_stats[i].nr_runnings;
63 busy_cpu = cpu_stats[i].num_busy_cpu;
65 down_condition = false;
67 if (last_time >= time)
72 /* Check level up condition */
73 for (j = 0; j < table[level].num_up_cond; j++) {
75 * If one more conditions are false among following
76 * conditions, don't increment up_count.
78 if (freq >= table[level].up_cond[j].freq
79 && nr_running >= table[level].up_cond[j].nr_running
80 && busy_cpu >= table[level].up_cond[j].busy_cpu)
84 if (table[level].num_up_cond && up_condition) {
88 _I("[Level%d] [up_count : %2d] \
89 freq(%d), nr_running(%d), busy_cpu(%d)",
91 table[level].up_cond[j].freq ? freq : -1,
92 table[level].up_cond[j].nr_running ? nr_running : -1,
93 table[level].up_cond[j].busy_cpu ? busy_cpu : -1);
97 /* Check level down condition */
98 for (j = 0; j < table[level].num_down_cond; j++) {
100 * If one more conditions are false among following
101 * conditions, don't increment down_count.
103 if (freq <= table[level].down_cond[j].freq
104 && nr_running < table[level].down_cond[j].nr_running
105 && busy_cpu < table[level].down_cond[j].busy_cpu)
106 down_condition = true;
109 if (table[level].num_down_cond && down_condition) {
113 _I("[Level%d] [dw_count : %2d] \
114 freq(%d), nr_running(%d), busy_cpu(%d)",
116 table[level].down_cond[j].freq ? freq : -1,
117 table[level].down_cond[j].nr_running ? nr_running : -1,
118 table[level].down_cond[j].busy_cpu ? busy_cpu : -1);
122 if (level < policy->max_level &&
123 freq == table[level].limit_max_freq)
130 if (up_count && level < policy->max_level &&
131 up_count * 100 >= num_pass_gov * up_threshold) {
133 } else if (down_count && level > policy->min_level &&
134 down_count * 100 >= num_pass_gov * down_threshold) {