summaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq
diff options
context:
space:
mode:
authorStratos Karafotis <stratosk@semaphore.gr>2016-11-16 12:26:29 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-11-16 17:15:56 -0500
commit00bfe05889e91b5112893b001e4a47b0a0f8bdd7 (patch)
treeb847ae15c976553f630761b18588232fa26285b1 /drivers/cpufreq
parentd5f905a93c321929ad8609c2478c1a5cd00aefdf (diff)
cpufreq: conservative: Decrease frequency faster for deferred updates
Conservative governor changes the CPU frequency in steps. That means that if a CPU runs at max frequency, it will need several sampling periods to return to min frequency when the workload is finished. If the update function that calculates the load and target frequency is deferred, the governor might need even more time to decrease the frequency. This may have impact to power consumption and after all conservative should decrease the frequency if there is no workload at every sampling rate. To resolve the above issue calculate the number of sampling periods that the update is deferred. Considering that for each sampling period conservative should drop the frequency by a freq_step because the CPU was idle apply the proper subtraction to requested frequency. Below, the kernel trace with and without this patch. First an intensive workload is applied on a specific CPU. Then the workload is removed and the CPU goes to idle. WITHOUT <idle>-0 [007] dN.. 620.329153: cpu_idle: state=4294967295 cpu_id=7 kworker/7:2-556 [007] .... 620.350857: cpu_frequency: state=1700000 cpu_id=7 kworker/7:2-556 [007] .... 620.370856: cpu_frequency: state=1900000 cpu_id=7 kworker/7:2-556 [007] .... 620.390854: cpu_frequency: state=2100000 cpu_id=7 kworker/7:2-556 [007] .... 620.411853: cpu_frequency: state=2200000 cpu_id=7 kworker/7:2-556 [007] .... 620.432854: cpu_frequency: state=2400000 cpu_id=7 kworker/7:2-556 [007] .... 620.453854: cpu_frequency: state=2600000 cpu_id=7 kworker/7:2-556 [007] .... 620.494856: cpu_frequency: state=2900000 cpu_id=7 kworker/7:2-556 [007] .... 620.515856: cpu_frequency: state=3100000 cpu_id=7 kworker/7:2-556 [007] .... 620.536858: cpu_frequency: state=3300000 cpu_id=7 kworker/7:2-556 [007] .... 620.557857: cpu_frequency: state=3401000 cpu_id=7 <idle>-0 [007] d... 669.591363: cpu_idle: state=4 cpu_id=7 <idle>-0 [007] d... 669.591939: cpu_idle: state=4294967295 cpu_id=7 <idle>-0 [007] d... 669.591980: cpu_idle: state=4 cpu_id=7 <idle>-0 [007] dN.. 669.591989: cpu_idle: state=4294967295 cpu_id=7 ... <idle>-0 [007] d... 670.201224: cpu_idle: state=4 cpu_id=7 <idle>-0 [007] d... 670.221975: cpu_idle: state=4294967295 cpu_id=7 kworker/7:2-556 [007] .... 670.222016: cpu_frequency: state=3300000 cpu_id=7 <idle>-0 [007] d... 670.222026: cpu_idle: state=4 cpu_id=7 <idle>-0 [007] d... 670.234964: cpu_idle: state=4294967295 cpu_id=7 ... <idle>-0 [007] d... 670.801251: cpu_idle: state=4 cpu_id=7 <idle>-0 [007] d... 671.236046: cpu_idle: state=4294967295 cpu_id=7 kworker/7:2-556 [007] .... 671.236073: cpu_frequency: state=3100000 cpu_id=7 <idle>-0 [007] d... 671.236112: cpu_idle: state=4 cpu_id=7 <idle>-0 [007] d... 671.393437: cpu_idle: state=4294967295 cpu_id=7 ... <idle>-0 [007] d... 671.401277: cpu_idle: state=4 cpu_id=7 <idle>-0 [007] d... 671.404083: cpu_idle: state=4294967295 cpu_id=7 kworker/7:2-556 [007] .... 671.404111: cpu_frequency: state=2900000 cpu_id=7 <idle>-0 [007] d... 671.404125: cpu_idle: state=4 cpu_id=7 <idle>-0 [007] d... 671.404974: cpu_idle: state=4294967295 cpu_id=7 ... <idle>-0 [007] d... 671.501180: cpu_idle: state=4 cpu_id=7 <idle>-0 [007] d... 671.995414: cpu_idle: state=4294967295 cpu_id=7 kworker/7:2-556 [007] .... 671.995459: cpu_frequency: state=2800000 cpu_id=7 <idle>-0 [007] d... 671.995469: cpu_idle: state=4 cpu_id=7 <idle>-0 [007] d... 671.996287: cpu_idle: state=4294967295 cpu_id=7 ... <idle>-0 [007] d... 672.001305: cpu_idle: state=4 cpu_id=7 <idle>-0 [007] d... 672.078374: cpu_idle: state=4294967295 cpu_id=7 kworker/7:2-556 [007] .... 672.078410: cpu_frequency: state=2600000 cpu_id=7 <idle>-0 [007] d... 672.078419: cpu_idle: state=4 cpu_id=7 <idle>-0 [007] d... 672.158020: cpu_idle: state=4294967295 cpu_id=7 kworker/7:2-556 [007] .... 672.158040: cpu_frequency: state=2400000 cpu_id=7 <idle>-0 [007] d... 672.158044: cpu_idle: state=4 cpu_id=7 <idle>-0 [007] d... 672.160038: cpu_idle: state=4294967295 cpu_id=7 ... <idle>-0 [007] d... 672.234557: cpu_idle: state=4 cpu_id=7 <idle>-0 [007] d... 672.237121: cpu_idle: state=4294967295 cpu_id=7 kworker/7:2-556 [007] .... 672.237174: cpu_frequency: state=2100000 cpu_id=7 <idle>-0 [007] d... 672.237186: cpu_idle: state=4 cpu_id=7 <idle>-0 [007] d... 672.237778: cpu_idle: state=4294967295 cpu_id=7 ... <idle>-0 [007] d... 672.267902: cpu_idle: state=4 cpu_id=7 <idle>-0 [007] d... 672.269860: cpu_idle: state=4294967295 cpu_id=7 kworker/7:2-556 [007] .... 672.269906: cpu_frequency: state=1900000 cpu_id=7 <idle>-0 [007] d... 672.269914: cpu_idle: state=4 cpu_id=7 <idle>-0 [007] d... 672.271902: cpu_idle: state=4294967295 cpu_id=7 ... <idle>-0 [007] d... 672.751342: cpu_idle: state=4 cpu_id=7 <idle>-0 [007] d... 672.823056: cpu_idle: state=4294967295 cpu_id=7 kworker/7:2-556 [007] .... 672.823095: cpu_frequency: state=1600000 cpu_id=7 WITH <idle>-0 [007] dN.. 4380.928009: cpu_idle: state=4294967295 cpu_id=7 kworker/7:2-399 [007] .... 4380.949767: cpu_frequency: state=2000000 cpu_id=7 kworker/7:2-399 [007] .... 4380.969765: cpu_frequency: state=2200000 cpu_id=7 kworker/7:2-399 [007] .... 4381.009766: cpu_frequency: state=2500000 cpu_id=7 kworker/7:2-399 [007] .... 4381.029767: cpu_frequency: state=2600000 cpu_id=7 kworker/7:2-399 [007] .... 4381.049769: cpu_frequency: state=2800000 cpu_id=7 kworker/7:2-399 [007] .... 4381.069769: cpu_frequency: state=3000000 cpu_id=7 kworker/7:2-399 [007] .... 4381.089771: cpu_frequency: state=3100000 cpu_id=7 kworker/7:2-399 [007] .... 4381.109772: cpu_frequency: state=3400000 cpu_id=7 kworker/7:2-399 [007] .... 4381.129773: cpu_frequency: state=3401000 cpu_id=7 <idle>-0 [007] d... 4428.226159: cpu_idle: state=1 cpu_id=7 <idle>-0 [007] d... 4428.226176: cpu_idle: state=4294967295 cpu_id=7 <idle>-0 [007] d... 4428.226181: cpu_idle: state=4 cpu_id=7 <idle>-0 [007] d... 4428.227177: cpu_idle: state=4294967295 cpu_id=7 ... <idle>-0 [007] d... 4428.551640: cpu_idle: state=4 cpu_id=7 <idle>-0 [007] d... 4428.649239: cpu_idle: state=4294967295 cpu_id=7 kworker/7:2-399 [007] .... 4428.649268: cpu_frequency: state=2800000 cpu_id=7 <idle>-0 [007] d... 4428.649278: cpu_idle: state=4 cpu_id=7 <idle>-0 [007] d... 4428.689856: cpu_idle: state=4294967295 cpu_id=7 ... <idle>-0 [007] d... 4428.799542: cpu_idle: state=4 cpu_id=7 <idle>-0 [007] d... 4428.801683: cpu_idle: state=4294967295 cpu_id=7 kworker/7:2-399 [007] .... 4428.801748: cpu_frequency: state=1700000 cpu_id=7 <idle>-0 [007] d... 4428.801761: cpu_idle: state=4 cpu_id=7 <idle>-0 [007] d... 4428.806545: cpu_idle: state=4294967295 cpu_id=7 ... <idle>-0 [007] d... 4429.051880: cpu_idle: state=4 cpu_id=7 <idle>-0 [007] d... 4429.086240: cpu_idle: state=4294967295 cpu_id=7 kworker/7:2-399 [007] .... 4429.086293: cpu_frequency: state=1600000 cpu_id=7 Without the patch the CPU dropped to min frequency after 3.2s With the patch applied the CPU dropped to min frequency after 0.86s Signed-off-by: Stratos Karafotis <stratosk@semaphore.gr> Acked-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/cpufreq')
-rw-r--r--drivers/cpufreq/cpufreq_conservative.c22
-rw-r--r--drivers/cpufreq/cpufreq_governor.c12
-rw-r--r--drivers/cpufreq/cpufreq_governor.h1
3 files changed, 31 insertions, 4 deletions
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
index 0681fcff5aae..a48b724768af 100644
--- a/drivers/cpufreq/cpufreq_conservative.c
+++ b/drivers/cpufreq/cpufreq_conservative.c
@@ -66,6 +66,7 @@ static unsigned int cs_dbs_update(struct cpufreq_policy *policy)
66 struct dbs_data *dbs_data = policy_dbs->dbs_data; 66 struct dbs_data *dbs_data = policy_dbs->dbs_data;
67 struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; 67 struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;
68 unsigned int load = dbs_update(policy); 68 unsigned int load = dbs_update(policy);
69 unsigned int freq_step;
69 70
70 /* 71 /*
71 * break out if we 'cannot' reduce the speed as the user might 72 * break out if we 'cannot' reduce the speed as the user might
@@ -82,6 +83,23 @@ static unsigned int cs_dbs_update(struct cpufreq_policy *policy)
82 if (requested_freq > policy->max || requested_freq < policy->min) 83 if (requested_freq > policy->max || requested_freq < policy->min)
83 requested_freq = policy->cur; 84 requested_freq = policy->cur;
84 85
86 freq_step = get_freq_step(cs_tuners, policy);
87
88 /*
89 * Decrease requested_freq one freq_step for each idle period that
90 * we didn't update the frequency.
91 */
92 if (policy_dbs->idle_periods < UINT_MAX) {
93 unsigned int freq_steps = policy_dbs->idle_periods * freq_step;
94
95 if (requested_freq > freq_steps)
96 requested_freq -= freq_steps;
97 else
98 requested_freq = policy->min;
99
100 policy_dbs->idle_periods = UINT_MAX;
101 }
102
85 /* Check for frequency increase */ 103 /* Check for frequency increase */
86 if (load > dbs_data->up_threshold) { 104 if (load > dbs_data->up_threshold) {
87 dbs_info->down_skip = 0; 105 dbs_info->down_skip = 0;
@@ -90,7 +108,7 @@ static unsigned int cs_dbs_update(struct cpufreq_policy *policy)
90 if (requested_freq == policy->max) 108 if (requested_freq == policy->max)
91 goto out; 109 goto out;
92 110
93 requested_freq += get_freq_step(cs_tuners, policy); 111 requested_freq += freq_step;
94 if (requested_freq > policy->max) 112 if (requested_freq > policy->max)
95 requested_freq = policy->max; 113 requested_freq = policy->max;
96 114
@@ -106,14 +124,12 @@ static unsigned int cs_dbs_update(struct cpufreq_policy *policy)
106 124
107 /* Check for frequency decrease */ 125 /* Check for frequency decrease */
108 if (load < cs_tuners->down_threshold) { 126 if (load < cs_tuners->down_threshold) {
109 unsigned int freq_step;
110 /* 127 /*
111 * if we cannot reduce the frequency anymore, break out early 128 * if we cannot reduce the frequency anymore, break out early
112 */ 129 */
113 if (requested_freq == policy->min) 130 if (requested_freq == policy->min)
114 goto out; 131 goto out;
115 132
116 freq_step = get_freq_step(cs_tuners, policy);
117 if (requested_freq > freq_step) 133 if (requested_freq > freq_step)
118 requested_freq -= freq_step; 134 requested_freq -= freq_step;
119 else 135 else
diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c
index 372947416b75..0196467280bd 100644
--- a/drivers/cpufreq/cpufreq_governor.c
+++ b/drivers/cpufreq/cpufreq_governor.c
@@ -117,7 +117,7 @@ unsigned int dbs_update(struct cpufreq_policy *policy)
117 struct policy_dbs_info *policy_dbs = policy->governor_data; 117 struct policy_dbs_info *policy_dbs = policy->governor_data;
118 struct dbs_data *dbs_data = policy_dbs->dbs_data; 118 struct dbs_data *dbs_data = policy_dbs->dbs_data;
119 unsigned int ignore_nice = dbs_data->ignore_nice_load; 119 unsigned int ignore_nice = dbs_data->ignore_nice_load;
120 unsigned int max_load = 0; 120 unsigned int max_load = 0, idle_periods = UINT_MAX;
121 unsigned int sampling_rate, io_busy, j; 121 unsigned int sampling_rate, io_busy, j;
122 122
123 /* 123 /*
@@ -215,9 +215,19 @@ unsigned int dbs_update(struct cpufreq_policy *policy)
215 j_cdbs->prev_load = load; 215 j_cdbs->prev_load = load;
216 } 216 }
217 217
218 if (time_elapsed > 2 * sampling_rate) {
219 unsigned int periods = time_elapsed / sampling_rate;
220
221 if (periods < idle_periods)
222 idle_periods = periods;
223 }
224
218 if (load > max_load) 225 if (load > max_load)
219 max_load = load; 226 max_load = load;
220 } 227 }
228
229 policy_dbs->idle_periods = idle_periods;
230
221 return max_load; 231 return max_load;
222} 232}
223EXPORT_SYMBOL_GPL(dbs_update); 233EXPORT_SYMBOL_GPL(dbs_update);
diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h
index 9660cc6b4b39..f5717ca070cc 100644
--- a/drivers/cpufreq/cpufreq_governor.h
+++ b/drivers/cpufreq/cpufreq_governor.h
@@ -97,6 +97,7 @@ struct policy_dbs_info {
97 struct list_head list; 97 struct list_head list;
98 /* Multiplier for increasing sample delay temporarily. */ 98 /* Multiplier for increasing sample delay temporarily. */
99 unsigned int rate_mult; 99 unsigned int rate_mult;
100 unsigned int idle_periods; /* For conservative */
100 /* Status indicators */ 101 /* Status indicators */
101 bool is_shared; /* This object is used by multiple CPUs */ 102 bool is_shared; /* This object is used by multiple CPUs */
102 bool work_in_progress; /* Work is being queued up or in progress */ 103 bool work_in_progress; /* Work is being queued up or in progress */