History

[CPUFREQ] Remove slowdown from ondemand sampling path.

Remove slowdown from ondemand sampling path. This reduces the code path length in dbs_check_cpu() by half. slowdown was not used by ondemand by default. If there are any user level tools that were using this tunable, they may report error now.

Venkatesh Pallipadi committed 20 years ago

Commit ccb2fe21 parent 501b7c72 files · +42 −98Browse files

Unified · Split

2 files
  1. drivers/cpufreq/cpufreq_ondemand.c +40 −98
  2. include/asm-generic/cputime.h +2 −0
drivers/cpufreq/cpufreq_ondemand.c+40−98
@@ -56,16 +56,14 @@ static unsigned int def_sampling_rate; · 55 unmodified lines
56#define MIN_SAMPLING_RATE (def_sampling_rate / MIN_SAMPLING_RATE_RATIO)56#define MIN_SAMPLING_RATE (def_sampling_rate / MIN_SAMPLING_RATE_RATIO)
57#define MAX_SAMPLING_RATE (500 * def_sampling_rate)57#define MAX_SAMPLING_RATE (500 * def_sampling_rate)
58#define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000)58#define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000)
59#define DEF_SAMPLING_DOWN_FACTOR (1)
60#define MAX_SAMPLING_DOWN_FACTOR (10)
61#define TRANSITION_LATENCY_LIMIT (10 * 1000)59#define TRANSITION_LATENCY_LIMIT (10 * 1000)
62 60
63static void do_dbs_timer(void *data);61static void do_dbs_timer(void *data);
64 62
65struct cpu_dbs_info_s {63struct cpu_dbs_info_s {
64 cputime64_t prev_cpu_idle;
65 cputime64_t prev_cpu_wall;
66 struct cpufreq_policy *cur_policy;66 struct cpufreq_policy *cur_policy;
67 unsigned int prev_cpu_idle_up;
68 unsigned int prev_cpu_idle_down;
69 unsigned int enable;67 unsigned int enable;
70};68};
71static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info);69static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info);
@@ -87,24 +85,26 @@ static struct workqueue_struct *dbs_workq; · 15 unmodified lines
87 85
88struct dbs_tuners {86struct dbs_tuners {
89 unsigned int sampling_rate;87 unsigned int sampling_rate;
90 unsigned int sampling_down_factor;
91 unsigned int up_threshold;88 unsigned int up_threshold;
92 unsigned int ignore_nice;89 unsigned int ignore_nice;
93};90};
94 91
95static struct dbs_tuners dbs_tuners_ins = {92static struct dbs_tuners dbs_tuners_ins = {
96 .up_threshold = DEF_FREQUENCY_UP_THRESHOLD,93 .up_threshold = DEF_FREQUENCY_UP_THRESHOLD,
97 .sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR,
98 .ignore_nice = 0,94 .ignore_nice = 0,
99};95};
100 96
101static inline unsigned int get_cpu_idle_time(unsigned int cpu)97static inline cputime64_t get_cpu_idle_time(unsigned int cpu)
102{98{
103 return kstat_cpu(cpu).cpustat.idle +99 cputime64_t retval;
104 kstat_cpu(cpu).cpustat.iowait +100
105 ( dbs_tuners_ins.ignore_nice ?101 retval = cputime64_add(kstat_cpu(cpu).cpustat.idle,
106 kstat_cpu(cpu).cpustat.nice :102 kstat_cpu(cpu).cpustat.iowait);
107 0);103
104 if (dbs_tuners_ins.ignore_nice)
105 retval = cputime64_add(retval, kstat_cpu(cpu).cpustat.nice);
106
107 return retval;
108}108}
109 109
110/************************** sysfs interface ************************/110/************************** sysfs interface ************************/
@@ -133,29 +133,9 @@ static ssize_t show_##file_name \ · 22 unmodified lines
133 return sprintf(buf, "%u\n", dbs_tuners_ins.object); \133 return sprintf(buf, "%u\n", dbs_tuners_ins.object); \
134}134}
135show_one(sampling_rate, sampling_rate);135show_one(sampling_rate, sampling_rate);
136show_one(sampling_down_factor, sampling_down_factor);
137show_one(up_threshold, up_threshold);136show_one(up_threshold, up_threshold);
138show_one(ignore_nice_load, ignore_nice);137show_one(ignore_nice_load, ignore_nice);
139 138
140static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused,
141 const char *buf, size_t count)
142{
143 unsigned int input;
144 int ret;
145 ret = sscanf (buf, "%u", &input);
146 if (ret != 1 )
147 return -EINVAL;
148
149 if (input > MAX_SAMPLING_DOWN_FACTOR || input < 1)
150 return -EINVAL;
151
152 mutex_lock(&dbs_mutex);
153 dbs_tuners_ins.sampling_down_factor = input;
154 mutex_unlock(&dbs_mutex);
155
156 return count;
157}
158
159static ssize_t store_sampling_rate(struct cpufreq_policy *unused,139static ssize_t store_sampling_rate(struct cpufreq_policy *unused,
160 const char *buf, size_t count)140 const char *buf, size_t count)
161{141{
@@ -217,12 +197,12 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy, · 55 unmodified lines
217 }197 }
218 dbs_tuners_ins.ignore_nice = input;198 dbs_tuners_ins.ignore_nice = input;
219 199
220 /* we need to re-evaluate prev_cpu_idle_up and prev_cpu_idle_down */200 /* we need to re-evaluate prev_cpu_idle */
221 for_each_online_cpu(j) {201 for_each_online_cpu(j) {
222 struct cpu_dbs_info_s *j_dbs_info;202 struct cpu_dbs_info_s *dbs_info;
223 j_dbs_info = &per_cpu(cpu_dbs_info, j);203 dbs_info = &per_cpu(cpu_dbs_info, j);
224 j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j);204 dbs_info->prev_cpu_idle = get_cpu_idle_time(j);
225 j_dbs_info->prev_cpu_idle_down = j_dbs_info->prev_cpu_idle_up;205 dbs_info->prev_cpu_wall = get_jiffies_64();
226 }206 }
227 mutex_unlock(&dbs_mutex);207 mutex_unlock(&dbs_mutex);
228 208
@@ -234,7 +214,6 @@ static struct freq_attr _name = \ · 5 unmodified lines
234__ATTR(_name, 0644, show_##_name, store_##_name)214__ATTR(_name, 0644, show_##_name, store_##_name)
235 215
236define_one_rw(sampling_rate);216define_one_rw(sampling_rate);
237define_one_rw(sampling_down_factor);
238define_one_rw(up_threshold);217define_one_rw(up_threshold);
239define_one_rw(ignore_nice_load);218define_one_rw(ignore_nice_load);
240 219
@@ -242,7 +221,6 @@ static struct attribute * dbs_attributes[] = { · 1 unmodified line
242 &sampling_rate_max.attr,221 &sampling_rate_max.attr,
243 &sampling_rate_min.attr,222 &sampling_rate_min.attr,
244 &sampling_rate.attr,223 &sampling_rate.attr,
245 &sampling_down_factor.attr,
246 &up_threshold.attr,224 &up_threshold.attr,
247 &ignore_nice_load.attr,225 &ignore_nice_load.attr,
248 NULL226 NULL
@@ -257,11 +235,10 @@ static struct attribute_group dbs_attr_group = { · 8 unmodified lines
257 235
258static void dbs_check_cpu(int cpu)236static void dbs_check_cpu(int cpu)
259{237{
260 unsigned int idle_ticks, up_idle_ticks, total_ticks;238 unsigned int idle_ticks, total_ticks;
261 unsigned int freq_next;239 unsigned int load;
262 unsigned int freq_down_sampling_rate;
263 static int down_skip[NR_CPUS];
264 struct cpu_dbs_info_s *this_dbs_info;240 struct cpu_dbs_info_s *this_dbs_info;
241 cputime64_t cur_jiffies;
265 242
266 struct cpufreq_policy *policy;243 struct cpufreq_policy *policy;
267 unsigned int j;244 unsigned int j;
@@ -271,10 +248,14 @@ static void dbs_check_cpu(int cpu) · 3 unmodified lines
271 return;248 return;
272 249
273 policy = this_dbs_info->cur_policy;250 policy = this_dbs_info->cur_policy;
251 cur_jiffies = jiffies64_to_cputime64(get_jiffies_64());
252 total_ticks = (unsigned int) cputime64_sub(cur_jiffies,
253 this_dbs_info->prev_cpu_wall);
254 this_dbs_info->prev_cpu_wall = cur_jiffies;
274 /*255 /*
275 * Every sampling_rate, we check, if current idle time is less256 * Every sampling_rate, we check, if current idle time is less
276 * than 20% (default), then we try to increase frequency257 * than 20% (default), then we try to increase frequency
277 * Every sampling_rate*sampling_down_factor, we look for a the lowest258 * Every sampling_rate, we look for a the lowest
278 * frequency which can sustain the load while keeping idle time over259 * frequency which can sustain the load while keeping idle time over
279 * 30%. If such a frequency exist, we try to decrease to this frequency.260 * 30%. If such a frequency exist, we try to decrease to this frequency.
280 *261 *
@@ -283,36 +264,26 @@ static void dbs_check_cpu(int cpu) · 2 unmodified lines
283 * 5% (default) of current frequency264 * 5% (default) of current frequency
284 */265 */
285 266
286 /* Check for frequency increase */267 /* Get Idle Time */
287 idle_ticks = UINT_MAX;268 idle_ticks = UINT_MAX;
288 for_each_cpu_mask(j, policy->cpus) {269 for_each_cpu_mask(j, policy->cpus) {
289 unsigned int tmp_idle_ticks, total_idle_ticks;270 cputime64_t total_idle_ticks;
271 unsigned int tmp_idle_ticks;
290 struct cpu_dbs_info_s *j_dbs_info;272 struct cpu_dbs_info_s *j_dbs_info;
291 273
292 j_dbs_info = &per_cpu(cpu_dbs_info, j);274 j_dbs_info = &per_cpu(cpu_dbs_info, j);
293 total_idle_ticks = get_cpu_idle_time(j);275 total_idle_ticks = get_cpu_idle_time(j);
294 tmp_idle_ticks = total_idle_ticks -276 tmp_idle_ticks = (unsigned int) cputime64_sub(total_idle_ticks,
295 j_dbs_info->prev_cpu_idle_up;277 j_dbs_info->prev_cpu_idle);
296 j_dbs_info->prev_cpu_idle_up = total_idle_ticks;278 j_dbs_info->prev_cpu_idle = total_idle_ticks;
297 279
298 if (tmp_idle_ticks < idle_ticks)280 if (tmp_idle_ticks < idle_ticks)
299 idle_ticks = tmp_idle_ticks;281 idle_ticks = tmp_idle_ticks;
300 }282 }
283 load = (100 * (total_ticks - idle_ticks)) / total_ticks;
301 284
302 /* Scale idle ticks by 100 and compare with up and down ticks */285 /* Check for frequency increase */
303 idle_ticks *= 100;286 if (load > dbs_tuners_ins.up_threshold) {
304 up_idle_ticks = (100 - dbs_tuners_ins.up_threshold) *
305 usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
306
307 if (idle_ticks < up_idle_ticks) {
308 down_skip[cpu] = 0;
309 for_each_cpu_mask(j, policy->cpus) {
310 struct cpu_dbs_info_s *j_dbs_info;
311
312 j_dbs_info = &per_cpu(cpu_dbs_info, j);
313 j_dbs_info->prev_cpu_idle_down =
314 j_dbs_info->prev_cpu_idle_up;
315 }
316 /* if we are already at full speed then break out early */287 /* if we are already at full speed then break out early */
317 if (policy->cur == policy->max)288 if (policy->cur == policy->max)
318 return;289 return;
@@ -323,50 +294,22 @@ static void dbs_check_cpu(int cpu) · 4 unmodified lines
323 }294 }
324 295
325 /* Check for frequency decrease */296 /* Check for frequency decrease */
326 down_skip[cpu]++;
327 if (down_skip[cpu] < dbs_tuners_ins.sampling_down_factor)
328 return;
329
330 idle_ticks = UINT_MAX;
331 for_each_cpu_mask(j, policy->cpus) {
332 unsigned int tmp_idle_ticks, total_idle_ticks;
333 struct cpu_dbs_info_s *j_dbs_info;
334
335 j_dbs_info = &per_cpu(cpu_dbs_info, j);
336 /* Check for frequency decrease */
337 total_idle_ticks = j_dbs_info->prev_cpu_idle_up;
338 tmp_idle_ticks = total_idle_ticks -
339 j_dbs_info->prev_cpu_idle_down;
340 j_dbs_info->prev_cpu_idle_down = total_idle_ticks;
341
342 if (tmp_idle_ticks < idle_ticks)
343 idle_ticks = tmp_idle_ticks;
344 }
345
346 down_skip[cpu] = 0;
347 /* if we cannot reduce the frequency anymore, break out early */297 /* if we cannot reduce the frequency anymore, break out early */
348 if (policy->cur == policy->min)298 if (policy->cur == policy->min)
349 return;299 return;
350 300
351 /* Compute how many ticks there are between two measurements */
352 freq_down_sampling_rate = dbs_tuners_ins.sampling_rate *
353 dbs_tuners_ins.sampling_down_factor;
354 total_ticks = usecs_to_jiffies(freq_down_sampling_rate);
355
356 /*301 /*
357 * The optimal frequency is the frequency that is the lowest that302 * The optimal frequency is the frequency that is the lowest that
358 * can support the current CPU usage without triggering the up303 * can support the current CPU usage without triggering the up
359 * policy. To be safe, we focus 10 points under the threshold.304 * policy. To be safe, we focus 10 points under the threshold.
360 */305 */
361 freq_next = ((total_ticks - idle_ticks) * 100) / total_ticks;306 if (load < (dbs_tuners_ins.up_threshold - 10)) {
362 freq_next = (freq_next * policy->cur) /307 unsigned int freq_next;
308 freq_next = (policy->cur * load) /
363 (dbs_tuners_ins.up_threshold - 10);309 (dbs_tuners_ins.up_threshold - 10);
364 310
365 if (freq_next < policy->min)
366 freq_next = policy->min;
367
368 if (freq_next <= ((policy->cur * 95) / 100))
369 __cpufreq_driver_target(policy, freq_next, CPUFREQ_RELATION_L);311 __cpufreq_driver_target(policy, freq_next, CPUFREQ_RELATION_L);
312 }
370}313}
371 314
372static void do_dbs_timer(void *data)315static void do_dbs_timer(void *data)
@@ -432,9 +375,8 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, · 59 unmodified lines
432 j_dbs_info = &per_cpu(cpu_dbs_info, j);375 j_dbs_info = &per_cpu(cpu_dbs_info, j);
433 j_dbs_info->cur_policy = policy;376 j_dbs_info->cur_policy = policy;
434 377
435 j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j);378 j_dbs_info->prev_cpu_idle = get_cpu_idle_time(j);
436 j_dbs_info->prev_cpu_idle_down379 j_dbs_info->prev_cpu_wall = get_jiffies_64();
437 = j_dbs_info->prev_cpu_idle_up;
438 }380 }
439 this_dbs_info->enable = 1;381 this_dbs_info->enable = 1;
440 sysfs_create_group(&policy->kobj, &dbs_attr_group);382 sysfs_create_group(&policy->kobj, &dbs_attr_group);
include/asm-generic/cputime.h+2−0
@@ -24,7 +24,9 @@ typedef u64 cputime64_t; · 23 unmodified lines
24 24
25#define cputime64_zero (0ULL)25#define cputime64_zero (0ULL)
26#define cputime64_add(__a, __b) ((__a) + (__b))26#define cputime64_add(__a, __b) ((__a) + (__b))
27#define cputime64_sub(__a, __b) ((__a) - (__b))
27#define cputime64_to_jiffies64(__ct) (__ct)28#define cputime64_to_jiffies64(__ct) (__ct)
29#define jiffies64_to_cputime64(__jif) (__jif)
28#define cputime_to_cputime64(__ct) ((u64) __ct)30#define cputime_to_cputime64(__ct) ((u64) __ct)
29 31
30 32