1 From: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
2 Subject: cpufreq, ondemand: Change the load calculation, optimizing for dependent cpus
4 Change the load calculation algorithm in ondemand to work well with software
5 coordination of frequency across the dependent cpus.
7 Multiply individual CPU utilization with the average freq of that logical CPU
8 during the measurement interval (using getavg call). And find the max CPU
9 utilization number in terms of CPU freq. That number is then used to
10 get to the target freq for next sampling interval.
12 Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
13 Signed-off-by: Thomas Renninger <trenn@suse.de>
16 drivers/cpufreq/cpufreq_ondemand.c | 65 +++++++++++++++++++------------------
17 1 file changed, 35 insertions(+), 30 deletions(-)
19 Index: cpufreq.git/drivers/cpufreq/cpufreq_ondemand.c
20 ===================================================================
21 --- cpufreq.git.orig/drivers/cpufreq/cpufreq_ondemand.c 2008-07-31 14:33:54.000000000 -0700
22 +++ cpufreq.git/drivers/cpufreq/cpufreq_ondemand.c 2008-07-31 14:52:01.000000000 -0700
23 @@ -334,9 +334,7 @@ static struct attribute_group dbs_attr_g
25 static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
27 - unsigned int idle_ticks, total_ticks;
28 - unsigned int load = 0;
29 - cputime64_t cur_jiffies;
30 + unsigned int max_load_freq;
32 struct cpufreq_policy *policy;
34 @@ -346,13 +344,7 @@ static void dbs_check_cpu(struct cpu_dbs
36 this_dbs_info->freq_lo = 0;
37 policy = this_dbs_info->cur_policy;
38 - cur_jiffies = jiffies64_to_cputime64(get_jiffies_64());
39 - total_ticks = (unsigned int) cputime64_sub(cur_jiffies,
40 - this_dbs_info->prev_cpu_wall);
41 - this_dbs_info->prev_cpu_wall = get_jiffies_64();
46 * Every sampling_rate, we check, if current idle time is less
47 * than 20% (default), then we try to increase frequency
48 @@ -365,27 +357,46 @@ static void dbs_check_cpu(struct cpu_dbs
49 * 5% (default) of current frequency
53 - idle_ticks = UINT_MAX;
54 + /* Get Absolute Load - in terms of freq */
57 for_each_cpu_mask_nr(j, policy->cpus) {
58 - cputime64_t total_idle_ticks;
59 - unsigned int tmp_idle_ticks;
60 struct cpu_dbs_info_s *j_dbs_info;
61 + cputime64_t cur_wall_time, cur_idle_time;
62 + unsigned int idle_time, wall_time;
63 + unsigned int load, load_freq;
66 j_dbs_info = &per_cpu(cpu_dbs_info, j);
67 - total_idle_ticks = get_cpu_idle_time(j);
68 - tmp_idle_ticks = (unsigned int) cputime64_sub(total_idle_ticks,
69 + cur_wall_time = jiffies64_to_cputime64(get_jiffies_64());
70 + wall_time = (unsigned int) cputime64_sub(cur_wall_time,
71 + j_dbs_info->prev_cpu_wall);
72 + j_dbs_info->prev_cpu_wall = cur_wall_time;
74 + cur_idle_time = get_cpu_idle_time(j);
75 + idle_time = (unsigned int) cputime64_sub(cur_idle_time,
76 j_dbs_info->prev_cpu_idle);
77 - j_dbs_info->prev_cpu_idle = total_idle_ticks;
78 + j_dbs_info->prev_cpu_idle = cur_idle_time;
80 + if (unlikely(wall_time <= idle_time ||
81 + (cputime_to_msecs(wall_time) <
82 + dbs_tuners_ins.sampling_rate / (2 * 1000)))) {
86 + load = 100 * (wall_time - idle_time) / wall_time;
88 - if (tmp_idle_ticks < idle_ticks)
89 - idle_ticks = tmp_idle_ticks;
90 + freq_avg = __cpufreq_driver_getavg(policy, j);
92 + freq_avg = policy->cur;
94 + load_freq = load * freq_avg;
95 + if (load_freq > max_load_freq)
96 + max_load_freq = load_freq;
98 - if (likely(total_ticks > idle_ticks))
99 - load = (100 * (total_ticks - idle_ticks)) / total_ticks;
101 /* Check for frequency increase */
102 - if (load > dbs_tuners_ins.up_threshold) {
103 + if (max_load_freq > dbs_tuners_ins.up_threshold * policy->cur) {
104 /* if we are already at full speed then break out early */
105 if (!dbs_tuners_ins.powersave_bias) {
106 if (policy->cur == policy->max)
107 @@ -412,15 +423,9 @@ static void dbs_check_cpu(struct cpu_dbs
108 * can support the current CPU usage without triggering the up
109 * policy. To be safe, we focus 10 points under the threshold.
111 - if (load < (dbs_tuners_ins.up_threshold - 10)) {
112 - unsigned int freq_next, freq_cur;
114 - freq_cur = __cpufreq_driver_getavg(policy, policy->cpu);
116 - freq_cur = policy->cur;
118 - freq_next = (freq_cur * load) /
119 - (dbs_tuners_ins.up_threshold - 10);
120 + if (max_load_freq < (dbs_tuners_ins.up_threshold - 10) * policy->cur) {
121 + unsigned int freq_next;
122 + freq_next = max_load_freq / (dbs_tuners_ins.up_threshold - 10);
124 if (!dbs_tuners_ins.powersave_bias) {
125 __cpufreq_driver_target(policy, freq_next,