diff options
Diffstat (limited to 'drivers/cpufreq/cpufreq_ondemand.c')
| -rw-r--r-- | drivers/cpufreq/cpufreq_ondemand.c | 260 | 
1 files changed, 91 insertions, 169 deletions
| diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 693e540481b4..87299924e735 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c | |||
| @@ -12,22 +12,11 @@ | |||
| 12 | 12 | ||
| 13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> | 
| 14 | #include <linux/module.h> | 14 | #include <linux/module.h> | 
| 15 | #include <linux/smp.h> | ||
| 16 | #include <linux/init.h> | 15 | #include <linux/init.h> | 
| 17 | #include <linux/interrupt.h> | ||
| 18 | #include <linux/ctype.h> | ||
| 19 | #include <linux/cpufreq.h> | 16 | #include <linux/cpufreq.h> | 
| 20 | #include <linux/sysctl.h> | ||
| 21 | #include <linux/types.h> | ||
| 22 | #include <linux/fs.h> | ||
| 23 | #include <linux/sysfs.h> | ||
| 24 | #include <linux/cpu.h> | 17 | #include <linux/cpu.h> | 
| 25 | #include <linux/sched.h> | ||
| 26 | #include <linux/kmod.h> | ||
| 27 | #include <linux/workqueue.h> | ||
| 28 | #include <linux/jiffies.h> | 18 | #include <linux/jiffies.h> | 
| 29 | #include <linux/kernel_stat.h> | 19 | #include <linux/kernel_stat.h> | 
| 30 | #include <linux/percpu.h> | ||
| 31 | #include <linux/mutex.h> | 20 | #include <linux/mutex.h> | 
| 32 | 21 | ||
| 33 | /* | 22 | /* | 
| @@ -56,16 +45,15 @@ static unsigned int def_sampling_rate; | |||
| 56 | #define MIN_SAMPLING_RATE (def_sampling_rate / MIN_SAMPLING_RATE_RATIO) | 45 | #define MIN_SAMPLING_RATE (def_sampling_rate / MIN_SAMPLING_RATE_RATIO) | 
| 57 | #define MAX_SAMPLING_RATE (500 * def_sampling_rate) | 46 | #define MAX_SAMPLING_RATE (500 * def_sampling_rate) | 
| 58 | #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000) | 47 | #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) | 48 | #define TRANSITION_LATENCY_LIMIT (10 * 1000) | 
| 62 | 49 | ||
| 63 | static void do_dbs_timer(void *data); | 50 | static void do_dbs_timer(void *data); | 
| 64 | 51 | ||
| 65 | struct cpu_dbs_info_s { | 52 | struct cpu_dbs_info_s { | 
| 53 | cputime64_t prev_cpu_idle; | ||
| 54 | cputime64_t prev_cpu_wall; | ||
| 66 | struct cpufreq_policy *cur_policy; | 55 | struct cpufreq_policy *cur_policy; | 
| 67 | unsigned int prev_cpu_idle_up; | 56 | struct work_struct work; | 
| 68 | unsigned int prev_cpu_idle_down; | ||
| 69 | unsigned int enable; | 57 | unsigned int enable; | 
| 70 | }; | 58 | }; | 
| 71 | static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info); | 59 | static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info); | 
| @@ -80,31 +68,32 @@ static unsigned int dbs_enable; /* number of CPUs using this policy */ | |||
| 80 | * cpu_hotplug lock should be taken before that. Note that cpu_hotplug lock | 68 | * cpu_hotplug lock should be taken before that. Note that cpu_hotplug lock | 
| 81 | * is recursive for the same process. -Venki | 69 | * is recursive for the same process. -Venki | 
| 82 | */ | 70 | */ | 
| 83 | static DEFINE_MUTEX (dbs_mutex); | 71 | static DEFINE_MUTEX(dbs_mutex); | 
| 84 | static DECLARE_WORK (dbs_work, do_dbs_timer, NULL); | ||
| 85 | 72 | ||
| 86 | static struct workqueue_struct *dbs_workq; | 73 | static struct workqueue_struct *kondemand_wq; | 
| 87 | 74 | ||
| 88 | struct dbs_tuners { | 75 | struct dbs_tuners { | 
| 89 | unsigned int sampling_rate; | 76 | unsigned int sampling_rate; | 
| 90 | unsigned int sampling_down_factor; | ||
| 91 | unsigned int up_threshold; | 77 | unsigned int up_threshold; | 
| 92 | unsigned int ignore_nice; | 78 | unsigned int ignore_nice; | 
| 93 | }; | 79 | }; | 
| 94 | 80 | ||
| 95 | static struct dbs_tuners dbs_tuners_ins = { | 81 | static struct dbs_tuners dbs_tuners_ins = { | 
| 96 | .up_threshold = DEF_FREQUENCY_UP_THRESHOLD, | 82 | .up_threshold = DEF_FREQUENCY_UP_THRESHOLD, | 
| 97 | .sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR, | ||
| 98 | .ignore_nice = 0, | 83 | .ignore_nice = 0, | 
| 99 | }; | 84 | }; | 
| 100 | 85 | ||
| 101 | static inline unsigned int get_cpu_idle_time(unsigned int cpu) | 86 | static inline cputime64_t get_cpu_idle_time(unsigned int cpu) | 
| 102 | { | 87 | { | 
| 103 | return kstat_cpu(cpu).cpustat.idle + | 88 | cputime64_t retval; | 
| 104 | kstat_cpu(cpu).cpustat.iowait + | 89 | |
| 105 | ( dbs_tuners_ins.ignore_nice ? | 90 | retval = cputime64_add(kstat_cpu(cpu).cpustat.idle, | 
| 106 | kstat_cpu(cpu).cpustat.nice : | 91 | kstat_cpu(cpu).cpustat.iowait); | 
| 107 | 0); | 92 | |
| 93 | if (dbs_tuners_ins.ignore_nice) | ||
| 94 | retval = cputime64_add(retval, kstat_cpu(cpu).cpustat.nice); | ||
| 95 | |||
| 96 | return retval; | ||
| 108 | } | 97 | } | 
| 109 | 98 | ||
| 110 | /************************** sysfs interface ************************/ | 99 | /************************** sysfs interface ************************/ | 
| @@ -133,35 +122,15 @@ static ssize_t show_##file_name \ | |||
| 133 | return sprintf(buf, "%u\n", dbs_tuners_ins.object); \ | 122 | return sprintf(buf, "%u\n", dbs_tuners_ins.object); \ | 
| 134 | } | 123 | } | 
| 135 | show_one(sampling_rate, sampling_rate); | 124 | show_one(sampling_rate, sampling_rate); | 
| 136 | show_one(sampling_down_factor, sampling_down_factor); | ||
| 137 | show_one(up_threshold, up_threshold); | 125 | show_one(up_threshold, up_threshold); | 
| 138 | show_one(ignore_nice_load, ignore_nice); | 126 | show_one(ignore_nice_load, ignore_nice); | 
| 139 | 127 | ||
| 140 | static 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 | |||
| 159 | static ssize_t store_sampling_rate(struct cpufreq_policy *unused, | 128 | static ssize_t store_sampling_rate(struct cpufreq_policy *unused, | 
| 160 | const char *buf, size_t count) | 129 | const char *buf, size_t count) | 
| 161 | { | 130 | { | 
| 162 | unsigned int input; | 131 | unsigned int input; | 
| 163 | int ret; | 132 | int ret; | 
| 164 | ret = sscanf (buf, "%u", &input); | 133 | ret = sscanf(buf, "%u", &input); | 
| 165 | 134 | ||
| 166 | mutex_lock(&dbs_mutex); | 135 | mutex_lock(&dbs_mutex); | 
| 167 | if (ret != 1 || input > MAX_SAMPLING_RATE || input < MIN_SAMPLING_RATE) { | 136 | if (ret != 1 || input > MAX_SAMPLING_RATE || input < MIN_SAMPLING_RATE) { | 
| @@ -180,7 +149,7 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused, | |||
| 180 | { | 149 | { | 
| 181 | unsigned int input; | 150 | unsigned int input; | 
| 182 | int ret; | 151 | int ret; | 
| 183 | ret = sscanf (buf, "%u", &input); | 152 | ret = sscanf(buf, "%u", &input); | 
| 184 | 153 | ||
| 185 | mutex_lock(&dbs_mutex); | 154 | mutex_lock(&dbs_mutex); | 
| 186 | if (ret != 1 || input > MAX_FREQUENCY_UP_THRESHOLD || | 155 | if (ret != 1 || input > MAX_FREQUENCY_UP_THRESHOLD || | 
| @@ -203,7 +172,7 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy, | |||
| 203 | 172 | ||
| 204 | unsigned int j; | 173 | unsigned int j; | 
| 205 | 174 | ||
| 206 | ret = sscanf (buf, "%u", &input); | 175 | ret = sscanf(buf, "%u", &input); | 
| 207 | if ( ret != 1 ) | 176 | if ( ret != 1 ) | 
| 208 | return -EINVAL; | 177 | return -EINVAL; | 
| 209 | 178 | ||
| @@ -217,12 +186,12 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy, | |||
| 217 | } | 186 | } | 
| 218 | dbs_tuners_ins.ignore_nice = input; | 187 | dbs_tuners_ins.ignore_nice = input; | 
| 219 | 188 | ||
| 220 | /* we need to re-evaluate prev_cpu_idle_up and prev_cpu_idle_down */ | 189 | /* we need to re-evaluate prev_cpu_idle */ | 
| 221 | for_each_online_cpu(j) { | 190 | for_each_online_cpu(j) { | 
| 222 | struct cpu_dbs_info_s *j_dbs_info; | 191 | struct cpu_dbs_info_s *dbs_info; | 
| 223 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | 192 | dbs_info = &per_cpu(cpu_dbs_info, j); | 
| 224 | j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j); | 193 | 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; | 194 | dbs_info->prev_cpu_wall = get_jiffies_64(); | 
| 226 | } | 195 | } | 
| 227 | mutex_unlock(&dbs_mutex); | 196 | mutex_unlock(&dbs_mutex); | 
| 228 | 197 | ||
| @@ -234,7 +203,6 @@ static struct freq_attr _name = \ | |||
| 234 | __ATTR(_name, 0644, show_##_name, store_##_name) | 203 | __ATTR(_name, 0644, show_##_name, store_##_name) | 
| 235 | 204 | ||
| 236 | define_one_rw(sampling_rate); | 205 | define_one_rw(sampling_rate); | 
| 237 | define_one_rw(sampling_down_factor); | ||
| 238 | define_one_rw(up_threshold); | 206 | define_one_rw(up_threshold); | 
| 239 | define_one_rw(ignore_nice_load); | 207 | define_one_rw(ignore_nice_load); | 
| 240 | 208 | ||
| @@ -242,7 +210,6 @@ static struct attribute * dbs_attributes[] = { | |||
| 242 | &sampling_rate_max.attr, | 210 | &sampling_rate_max.attr, | 
| 243 | &sampling_rate_min.attr, | 211 | &sampling_rate_min.attr, | 
| 244 | &sampling_rate.attr, | 212 | &sampling_rate.attr, | 
| 245 | &sampling_down_factor.attr, | ||
| 246 | &up_threshold.attr, | 213 | &up_threshold.attr, | 
| 247 | &ignore_nice_load.attr, | 214 | &ignore_nice_load.attr, | 
| 248 | NULL | 215 | NULL | 
| @@ -255,26 +222,27 @@ static struct attribute_group dbs_attr_group = { | |||
| 255 | 222 | ||
| 256 | /************************** sysfs end ************************/ | 223 | /************************** sysfs end ************************/ | 
| 257 | 224 | ||
| 258 | static void dbs_check_cpu(int cpu) | 225 | static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) | 
| 259 | { | 226 | { | 
| 260 | unsigned int idle_ticks, up_idle_ticks, total_ticks; | 227 | unsigned int idle_ticks, total_ticks; | 
| 261 | unsigned int freq_next; | 228 | unsigned int load; | 
| 262 | unsigned int freq_down_sampling_rate; | 229 | cputime64_t cur_jiffies; | 
| 263 | static int down_skip[NR_CPUS]; | ||
| 264 | struct cpu_dbs_info_s *this_dbs_info; | ||
| 265 | 230 | ||
| 266 | struct cpufreq_policy *policy; | 231 | struct cpufreq_policy *policy; | 
| 267 | unsigned int j; | 232 | unsigned int j; | 
| 268 | 233 | ||
| 269 | this_dbs_info = &per_cpu(cpu_dbs_info, cpu); | ||
| 270 | if (!this_dbs_info->enable) | 234 | if (!this_dbs_info->enable) | 
| 271 | return; | 235 | return; | 
| 272 | 236 | ||
| 273 | policy = this_dbs_info->cur_policy; | 237 | policy = this_dbs_info->cur_policy; | 
| 238 | cur_jiffies = jiffies64_to_cputime64(get_jiffies_64()); | ||
| 239 | total_ticks = (unsigned int) cputime64_sub(cur_jiffies, | ||
| 240 | this_dbs_info->prev_cpu_wall); | ||
| 241 | this_dbs_info->prev_cpu_wall = cur_jiffies; | ||
| 274 | /* | 242 | /* | 
| 275 | * Every sampling_rate, we check, if current idle time is less | 243 | * Every sampling_rate, we check, if current idle time is less | 
| 276 | * than 20% (default), then we try to increase frequency | 244 | * than 20% (default), then we try to increase frequency | 
| 277 | * Every sampling_rate*sampling_down_factor, we look for a the lowest | 245 | * Every sampling_rate, we look for a the lowest | 
| 278 | * frequency which can sustain the load while keeping idle time over | 246 | * 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. | 247 | * 30%. If such a frequency exist, we try to decrease to this frequency. | 
| 280 | * | 248 | * | 
| @@ -283,36 +251,26 @@ static void dbs_check_cpu(int cpu) | |||
| 283 | * 5% (default) of current frequency | 251 | * 5% (default) of current frequency | 
| 284 | */ | 252 | */ | 
| 285 | 253 | ||
| 286 | /* Check for frequency increase */ | 254 | /* Get Idle Time */ | 
| 287 | idle_ticks = UINT_MAX; | 255 | idle_ticks = UINT_MAX; | 
| 288 | for_each_cpu_mask(j, policy->cpus) { | 256 | for_each_cpu_mask(j, policy->cpus) { | 
| 289 | unsigned int tmp_idle_ticks, total_idle_ticks; | 257 | cputime64_t total_idle_ticks; | 
| 258 | unsigned int tmp_idle_ticks; | ||
| 290 | struct cpu_dbs_info_s *j_dbs_info; | 259 | struct cpu_dbs_info_s *j_dbs_info; | 
| 291 | 260 | ||
| 292 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | 261 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | 
| 293 | total_idle_ticks = get_cpu_idle_time(j); | 262 | total_idle_ticks = get_cpu_idle_time(j); | 
| 294 | tmp_idle_ticks = total_idle_ticks - | 263 | tmp_idle_ticks = (unsigned int) cputime64_sub(total_idle_ticks, | 
| 295 | j_dbs_info->prev_cpu_idle_up; | 264 | j_dbs_info->prev_cpu_idle); | 
| 296 | j_dbs_info->prev_cpu_idle_up = total_idle_ticks; | 265 | j_dbs_info->prev_cpu_idle = total_idle_ticks; | 
| 297 | 266 | ||
| 298 | if (tmp_idle_ticks < idle_ticks) | 267 | if (tmp_idle_ticks < idle_ticks) | 
| 299 | idle_ticks = tmp_idle_ticks; | 268 | idle_ticks = tmp_idle_ticks; | 
| 300 | } | 269 | } | 
| 270 | load = (100 * (total_ticks - idle_ticks)) / total_ticks; | ||
| 301 | 271 | ||
| 302 | /* Scale idle ticks by 100 and compare with up and down ticks */ | 272 | /* Check for frequency increase */ | 
| 303 | idle_ticks *= 100; | 273 | 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 */ | 274 | /* if we are already at full speed then break out early */ | 
| 317 | if (policy->cur == policy->max) | 275 | if (policy->cur == policy->max) | 
| 318 | return; | 276 | return; | 
| @@ -323,83 +281,49 @@ static void dbs_check_cpu(int cpu) | |||
| 323 | } | 281 | } | 
| 324 | 282 | ||
| 325 | /* Check for frequency decrease */ | 283 | /* 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 */ | 284 | /* if we cannot reduce the frequency anymore, break out early */ | 
| 348 | if (policy->cur == policy->min) | 285 | if (policy->cur == policy->min) | 
| 349 | return; | 286 | return; | 
| 350 | 287 | ||
| 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 | /* | 288 | /* | 
| 357 | * The optimal frequency is the frequency that is the lowest that | 289 | * The optimal frequency is the frequency that is the lowest that | 
| 358 | * can support the current CPU usage without triggering the up | 290 | * can support the current CPU usage without triggering the up | 
| 359 | * policy. To be safe, we focus 10 points under the threshold. | 291 | * policy. To be safe, we focus 10 points under the threshold. | 
| 360 | */ | 292 | */ | 
| 361 | freq_next = ((total_ticks - idle_ticks) * 100) / total_ticks; | 293 | if (load < (dbs_tuners_ins.up_threshold - 10)) { | 
| 362 | freq_next = (freq_next * policy->cur) / | 294 | unsigned int freq_next; | 
| 295 | freq_next = (policy->cur * load) / | ||
| 363 | (dbs_tuners_ins.up_threshold - 10); | 296 | (dbs_tuners_ins.up_threshold - 10); | 
| 364 | 297 | ||
| 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); | 298 | __cpufreq_driver_target(policy, freq_next, CPUFREQ_RELATION_L); | 
| 299 | } | ||
| 370 | } | 300 | } | 
| 371 | 301 | ||
| 372 | static void do_dbs_timer(void *data) | 302 | static void do_dbs_timer(void *data) | 
| 373 | { | 303 | { | 
| 374 | int i; | 304 | unsigned int cpu = smp_processor_id(); | 
| 375 | lock_cpu_hotplug(); | 305 | struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, cpu); | 
| 376 | mutex_lock(&dbs_mutex); | 306 | |
| 377 | for_each_online_cpu(i) | 307 | dbs_check_cpu(dbs_info); | 
| 378 | dbs_check_cpu(i); | 308 | queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, | 
| 379 | queue_delayed_work(dbs_workq, &dbs_work, | 309 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); | 
| 380 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); | ||
| 381 | mutex_unlock(&dbs_mutex); | ||
| 382 | unlock_cpu_hotplug(); | ||
| 383 | } | 310 | } | 
| 384 | 311 | ||
| 385 | static inline void dbs_timer_init(void) | 312 | static inline void dbs_timer_init(unsigned int cpu) | 
| 386 | { | 313 | { | 
| 387 | INIT_WORK(&dbs_work, do_dbs_timer, NULL); | 314 | struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, cpu); | 
| 388 | if (!dbs_workq) | 315 | |
| 389 | dbs_workq = create_singlethread_workqueue("ondemand"); | 316 | INIT_WORK(&dbs_info->work, do_dbs_timer, 0); | 
| 390 | if (!dbs_workq) { | 317 | queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, | 
| 391 | printk(KERN_ERR "ondemand: Cannot initialize kernel thread\n"); | 318 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); | 
| 392 | return; | ||
| 393 | } | ||
| 394 | queue_delayed_work(dbs_workq, &dbs_work, | ||
| 395 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); | ||
| 396 | return; | 319 | return; | 
| 397 | } | 320 | } | 
| 398 | 321 | ||
| 399 | static inline void dbs_timer_exit(void) | 322 | static inline void dbs_timer_exit(unsigned int cpu) | 
| 400 | { | 323 | { | 
| 401 | if (dbs_workq) | 324 | struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, cpu); | 
| 402 | cancel_rearming_delayed_workqueue(dbs_workq, &dbs_work); | 325 | |
| 326 | cancel_rearming_delayed_workqueue(kondemand_wq, &dbs_info->work); | ||
| 403 | } | 327 | } | 
| 404 | 328 | ||
| 405 | static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | 329 | static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | 
| @@ -413,8 +337,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
| 413 | 337 | ||
| 414 | switch (event) { | 338 | switch (event) { | 
| 415 | case CPUFREQ_GOV_START: | 339 | case CPUFREQ_GOV_START: | 
| 416 | if ((!cpu_online(cpu)) || | 340 | if ((!cpu_online(cpu)) || (!policy->cur)) | 
| 417 | (!policy->cur)) | ||
| 418 | return -EINVAL; | 341 | return -EINVAL; | 
| 419 | 342 | ||
| 420 | if (policy->cpuinfo.transition_latency > | 343 | if (policy->cpuinfo.transition_latency > | 
| @@ -427,18 +350,26 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
| 427 | break; | 350 | break; | 
| 428 | 351 | ||
| 429 | mutex_lock(&dbs_mutex); | 352 | mutex_lock(&dbs_mutex); | 
| 353 | dbs_enable++; | ||
| 354 | if (dbs_enable == 1) { | ||
| 355 | kondemand_wq = create_workqueue("kondemand"); | ||
| 356 | if (!kondemand_wq) { | ||
| 357 | printk(KERN_ERR "Creation of kondemand failed\n"); | ||
| 358 | dbs_enable--; | ||
| 359 | mutex_unlock(&dbs_mutex); | ||
| 360 | return -ENOSPC; | ||
| 361 | } | ||
| 362 | } | ||
| 430 | for_each_cpu_mask(j, policy->cpus) { | 363 | for_each_cpu_mask(j, policy->cpus) { | 
| 431 | struct cpu_dbs_info_s *j_dbs_info; | 364 | struct cpu_dbs_info_s *j_dbs_info; | 
| 432 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | 365 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | 
| 433 | j_dbs_info->cur_policy = policy; | 366 | j_dbs_info->cur_policy = policy; | 
| 434 | 367 | ||
| 435 | j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j); | 368 | j_dbs_info->prev_cpu_idle = get_cpu_idle_time(j); | 
| 436 | j_dbs_info->prev_cpu_idle_down | 369 | j_dbs_info->prev_cpu_wall = get_jiffies_64(); | 
| 437 | = j_dbs_info->prev_cpu_idle_up; | ||
| 438 | } | 370 | } | 
| 439 | this_dbs_info->enable = 1; | 371 | this_dbs_info->enable = 1; | 
| 440 | sysfs_create_group(&policy->kobj, &dbs_attr_group); | 372 | sysfs_create_group(&policy->kobj, &dbs_attr_group); | 
| 441 | dbs_enable++; | ||
| 442 | /* | 373 | /* | 
| 443 | * Start the timerschedule work, when this governor | 374 | * Start the timerschedule work, when this governor | 
| 444 | * is used for first time | 375 | * is used for first time | 
| @@ -457,23 +388,20 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
| 457 | def_sampling_rate = MIN_STAT_SAMPLING_RATE; | 388 | def_sampling_rate = MIN_STAT_SAMPLING_RATE; | 
| 458 | 389 | ||
| 459 | dbs_tuners_ins.sampling_rate = def_sampling_rate; | 390 | dbs_tuners_ins.sampling_rate = def_sampling_rate; | 
| 460 | dbs_timer_init(); | ||
| 461 | } | 391 | } | 
| 392 | dbs_timer_init(policy->cpu); | ||
| 462 | 393 | ||
| 463 | mutex_unlock(&dbs_mutex); | 394 | mutex_unlock(&dbs_mutex); | 
| 464 | break; | 395 | break; | 
| 465 | 396 | ||
| 466 | case CPUFREQ_GOV_STOP: | 397 | case CPUFREQ_GOV_STOP: | 
| 467 | mutex_lock(&dbs_mutex); | 398 | mutex_lock(&dbs_mutex); | 
| 399 | dbs_timer_exit(policy->cpu); | ||
| 468 | this_dbs_info->enable = 0; | 400 | this_dbs_info->enable = 0; | 
| 469 | sysfs_remove_group(&policy->kobj, &dbs_attr_group); | 401 | sysfs_remove_group(&policy->kobj, &dbs_attr_group); | 
| 470 | dbs_enable--; | 402 | dbs_enable--; | 
| 471 | /* | ||
| 472 | * Stop the timerschedule work, when this governor | ||
| 473 | * is used for first time | ||
| 474 | */ | ||
| 475 | if (dbs_enable == 0) | 403 | if (dbs_enable == 0) | 
| 476 | dbs_timer_exit(); | 404 | destroy_workqueue(kondemand_wq); | 
| 477 | 405 | ||
| 478 | mutex_unlock(&dbs_mutex); | 406 | mutex_unlock(&dbs_mutex); | 
| 479 | 407 | ||
| @@ -483,13 +411,13 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
| 483 | lock_cpu_hotplug(); | 411 | lock_cpu_hotplug(); | 
| 484 | mutex_lock(&dbs_mutex); | 412 | mutex_lock(&dbs_mutex); | 
| 485 | if (policy->max < this_dbs_info->cur_policy->cur) | 413 | if (policy->max < this_dbs_info->cur_policy->cur) | 
| 486 | __cpufreq_driver_target( | 414 | __cpufreq_driver_target(this_dbs_info->cur_policy, | 
| 487 | this_dbs_info->cur_policy, | 415 | policy->max, | 
| 488 | policy->max, CPUFREQ_RELATION_H); | 416 | CPUFREQ_RELATION_H); | 
| 489 | else if (policy->min > this_dbs_info->cur_policy->cur) | 417 | else if (policy->min > this_dbs_info->cur_policy->cur) | 
| 490 | __cpufreq_driver_target( | 418 | __cpufreq_driver_target(this_dbs_info->cur_policy, | 
| 491 | this_dbs_info->cur_policy, | 419 | policy->min, | 
| 492 | policy->min, CPUFREQ_RELATION_L); | 420 | CPUFREQ_RELATION_L); | 
| 493 | mutex_unlock(&dbs_mutex); | 421 | mutex_unlock(&dbs_mutex); | 
| 494 | unlock_cpu_hotplug(); | 422 | unlock_cpu_hotplug(); | 
| 495 | break; | 423 | break; | 
| @@ -498,9 +426,9 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
| 498 | } | 426 | } | 
| 499 | 427 | ||
| 500 | static struct cpufreq_governor cpufreq_gov_dbs = { | 428 | static struct cpufreq_governor cpufreq_gov_dbs = { | 
| 501 | .name = "ondemand", | 429 | .name = "ondemand", | 
| 502 | .governor = cpufreq_governor_dbs, | 430 | .governor = cpufreq_governor_dbs, | 
| 503 | .owner = THIS_MODULE, | 431 | .owner = THIS_MODULE, | 
| 504 | }; | 432 | }; | 
| 505 | 433 | ||
| 506 | static int __init cpufreq_gov_dbs_init(void) | 434 | static int __init cpufreq_gov_dbs_init(void) | 
| @@ -510,21 +438,15 @@ static int __init cpufreq_gov_dbs_init(void) | |||
| 510 | 438 | ||
| 511 | static void __exit cpufreq_gov_dbs_exit(void) | 439 | static void __exit cpufreq_gov_dbs_exit(void) | 
| 512 | { | 440 | { | 
| 513 | /* Make sure that the scheduled work is indeed not running. | ||
| 514 | Assumes the timer has been cancelled first. */ | ||
| 515 | if (dbs_workq) { | ||
| 516 | flush_workqueue(dbs_workq); | ||
| 517 | destroy_workqueue(dbs_workq); | ||
| 518 | } | ||
| 519 | |||
| 520 | cpufreq_unregister_governor(&cpufreq_gov_dbs); | 441 | cpufreq_unregister_governor(&cpufreq_gov_dbs); | 
| 521 | } | 442 | } | 
| 522 | 443 | ||
| 523 | 444 | ||
| 524 | MODULE_AUTHOR ("Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>"); | 445 | MODULE_AUTHOR("Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>"); | 
| 525 | MODULE_DESCRIPTION ("'cpufreq_ondemand' - A dynamic cpufreq governor for " | 446 | MODULE_AUTHOR("Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>"); | 
| 526 | "Low Latency Frequency Transition capable processors"); | 447 | MODULE_DESCRIPTION("'cpufreq_ondemand' - A dynamic cpufreq governor for " | 
| 527 | MODULE_LICENSE ("GPL"); | 448 | "Low Latency Frequency Transition capable processors"); | 
| 449 | MODULE_LICENSE("GPL"); | ||
| 528 | 450 | ||
| 529 | module_init(cpufreq_gov_dbs_init); | 451 | module_init(cpufreq_gov_dbs_init); | 
| 530 | module_exit(cpufreq_gov_dbs_exit); | 452 | module_exit(cpufreq_gov_dbs_exit); | 
