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_radiation_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_radiation_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;
59 static int64_t last_time = 0;
61 for (i = 0; i < policy->num_pass_cpu_stats; i++) {
62 time = cpu_stats[i].time;
63 freq = cpu_stats[i].freq;
64 nr_running = cpu_stats[i].nr_runnings;
65 busy_cpu = cpu_stats[i].num_busy_cpu;
67 down_condition = true;
68 left_condition = true;
69 right_condition = true;
71 if (last_time >= time)
77 _I("[Level%d][%d][%lld] %d | %d | %d", level, i, time, freq,
78 nr_running, busy_cpu);
81 /* Check level up condition */
82 for (j = 0; j < table[level].num_up_cond && up_condition; j++) {
83 if (table[level].up_cond[j].freq &&
84 !(freq >= table[level].up_cond[j].freq))
88 if (table[level].num_up_cond && up_condition) {
92 _I("[Level%d] [up_count : %2d] \
93 freq(%d), nr_running(%d), busy_cpu(%d)",
95 table[level].up_cond[j].freq ? freq : -1,
99 /* Check level down condition */
100 for (j = 0; j < table[level].num_down_cond && down_condition; j++) {
101 if (table[level].down_cond[j].freq
102 && !(freq <= table[level].down_cond[j].freq))
103 down_condition = false;
106 if (table[level].num_down_cond && down_condition) {
110 _I("[Level%d] [dw_count : %2d] \
111 freq(%d), nr_running(%d), busy_cpu(%d)",
113 table[level].down_cond[j].freq ? freq : -1,
117 /* Check level right condition */
118 for (j = 0; j < table[level].num_right_cond && right_condition; j++) {
120 * If one more conditions are false among following
121 * conditions, don't increment right_count.
123 if (table[level].right_cond[j].nr_running
124 && !(nr_running > table[level].right_cond[j].nr_running))
125 right_condition = false;
127 if (table[level].right_cond[j].busy_cpu
128 && !(busy_cpu >= table[level].right_cond[j].busy_cpu))
129 right_condition = false;
132 if (table[level].num_right_cond && right_condition) {
136 _I("[Level%d] [right_count : %2d] \
137 nr_running(%d), busy_cpu(%d)",
139 table[level].right_cond[j].nr_running ? nr_running : -1,
140 table[level].right_cond[j].busy_cpu ? busy_cpu : -1);
144 /* Check level left condition */
145 for (j = 0; j < table[level].num_left_cond && left_condition; j++) {
147 * If one more conditions are false among following
148 * conditions, don't increment left_count.
150 if (table[level].left_cond[j].nr_running
151 && !(nr_running <= table[level].left_cond[j].nr_running))
152 left_condition = false;
154 if (table[level].left_cond[j].busy_cpu
155 && !(busy_cpu < table[level].left_cond[j].busy_cpu))
156 left_condition = false;
159 if (table[level].num_left_cond && left_condition) {
163 _I("[Level%d] [ left_count : %2d] \
164 nr_running(%d), busy_cpu(%d)",
166 table[level].left_cond[j].nr_running ? nr_running : -1,
167 table[level].left_cond[j].busy_cpu ? busy_cpu : -1);
172 if (up_count * 100 >= num_pass_gov * up_threshold)
173 level += policy->cpufreq.num_nr_cpus;
174 else if (down_count * 100 >= num_pass_gov * down_threshold)
175 level -= policy->cpufreq.num_nr_cpus;
177 if (right_count * 100 >= num_pass_gov * up_threshold)
179 else if (left_count * 100 >= num_pass_gov * down_threshold)
183 if (level == policy->prev_level) {
184 for (i = num_pass_gov; i < policy->num_pass_cpu_stats; i++) {
185 time = cpu_stats[i].time;
186 freq = cpu_stats[i].freq;
187 nr_running = cpu_stats[i].nr_runnings;
188 busy_cpu = cpu_stats[i].num_busy_cpu;
190 _I("[Level%d][%d][%lld] %d | %d | %d",
191 level, i, time, freq,
192 nr_running, busy_cpu);
196 if (level != policy->curr_level) {
197 _I("\n[Level%d] num_pass_gov: [%2d]", level, num_pass_gov);
198 _I("[Level%d] down_count : %2d (%3d >= %3d)", level, down_count,
199 down_count * 100, num_pass_gov * down_threshold);
200 _I("[Level%d] up_count : %2d (%3d >= %3d)", level, up_count,
201 up_count * 100, num_pass_gov * up_threshold);
202 _I("[Level%d] left_count : %2d (%3d >= %3d)", level, left_count,
203 left_count * 100, num_pass_gov * down_threshold);
204 _I("[Level%d] right_count : %2d (%3d >= %3d)", level, right_count,
205 right_count * 100, num_pass_gov * up_threshold);