Blame view

drivers/cpufreq/cpufreq_ondemand.c 20.9 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  /*
   *  drivers/cpufreq/cpufreq_ondemand.c
   *
   *  Copyright (C)  2001 Russell King
   *            (C)  2003 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>.
   *                      Jun Nakajima <jun.nakajima@intel.com>
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
   * published by the Free Software Foundation.
   */
  
  #include <linux/kernel.h>
  #include <linux/module.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
15
  #include <linux/init.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
16
  #include <linux/cpufreq.h>
138a0128c   Andrew Morton   [PATCH] cpufreq b...
17
  #include <linux/cpu.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18
19
  #include <linux/jiffies.h>
  #include <linux/kernel_stat.h>
3fc54d37a   Andrew Morton   [CPUFREQ] Convert...
20
  #include <linux/mutex.h>
808009131   venkatesh.pallipadi@intel.com   [CPUFREQ][6/6] cp...
21
22
23
  #include <linux/hrtimer.h>
  #include <linux/tick.h>
  #include <linux/ktime.h>
9411b4ef7   Thomas Renninger   [CPUFREQ] ondeman...
24
  #include <linux/sched.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
25
26
27
28
29
  
  /*
   * dbs is used in this file as a shortform for demandbased switching
   * It helps to keep variable names smaller, simpler
   */
e9d95bf7e   venkatesh.pallipadi@intel.com   [CPUFREQ][4/6] cp...
30
  #define DEF_FREQUENCY_DOWN_DIFFERENTIAL		(10)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31
  #define DEF_FREQUENCY_UP_THRESHOLD		(80)
3f78a9f7f   David C Niemi   [CPUFREQ] add sam...
32
33
  #define DEF_SAMPLING_DOWN_FACTOR		(1)
  #define MAX_SAMPLING_DOWN_FACTOR		(100000)
808009131   venkatesh.pallipadi@intel.com   [CPUFREQ][6/6] cp...
34
35
  #define MICRO_FREQUENCY_DOWN_DIFFERENTIAL	(3)
  #define MICRO_FREQUENCY_UP_THRESHOLD		(95)
cef9615a8   Thomas Renninger   [CPUFREQ] ondeman...
36
  #define MICRO_FREQUENCY_MIN_SAMPLE_RATE		(10000)
c29f14030   Dave Jones   [CPUFREQ] ondeman...
37
  #define MIN_FREQUENCY_UP_THRESHOLD		(11)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
38
  #define MAX_FREQUENCY_UP_THRESHOLD		(100)
32ee8c3e4   Dave Jones   [CPUFREQ] Lots of...
39
40
  /*
   * The polling frequency of this governor depends on the capability of
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
41
   * the processor. Default polling frequency is 1000 times the transition
32ee8c3e4   Dave Jones   [CPUFREQ] Lots of...
42
43
   * latency of the processor. The governor will work on any processor with
   * transition latency <= 10mS, using appropriate sampling
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
44
45
46
47
48
   * rate.
   * For CPUs with transition latency > 10mS (mostly drivers with CPUFREQ_ETERNAL)
   * this governor will not work.
   * All times here are in uS.
   */
df8b59be0   Dave Jones   [CPUFREQ] Avoid t...
49
  #define MIN_SAMPLING_RATE_RATIO			(2)
112124ab0   Thomas Renninger   [CPUFREQ] ondeman...
50

cef9615a8   Thomas Renninger   [CPUFREQ] ondeman...
51
  static unsigned int min_sampling_rate;
112124ab0   Thomas Renninger   [CPUFREQ] ondeman...
52
  #define LATENCY_MULTIPLIER			(1000)
cef9615a8   Thomas Renninger   [CPUFREQ] ondeman...
53
  #define MIN_LATENCY_MULTIPLIER			(100)
1c2562459   Thomas Renninger   [CPUFREQ] allow o...
54
  #define TRANSITION_LATENCY_LIMIT		(10 * 1000 * 1000)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
55

c4028958b   David Howells   WorkStruct: make ...
56
  static void do_dbs_timer(struct work_struct *work);
0e625ac15   Thomas Renninger   [CPUFREQ] ondeman...
57
58
59
60
61
62
63
64
65
66
67
68
  static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
  				unsigned int event);
  
  #ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND
  static
  #endif
  struct cpufreq_governor cpufreq_gov_ondemand = {
         .name                   = "ondemand",
         .governor               = cpufreq_governor_dbs,
         .max_transition_latency = TRANSITION_LATENCY_LIMIT,
         .owner                  = THIS_MODULE,
  };
c4028958b   David Howells   WorkStruct: make ...
69
70
  
  /* Sampling types */
529af7a14   Venkatesh Pallipadi   [CPUFREQ] ondeman...
71
  enum {DBS_NORMAL_SAMPLE, DBS_SUB_SAMPLE};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
72
73
  
  struct cpu_dbs_info_s {
ccb2fe209   Venkatesh Pallipadi   [CPUFREQ] Remove ...
74
  	cputime64_t prev_cpu_idle;
6b8fcd902   Arjan van de Ven   ondemand: Solve a...
75
  	cputime64_t prev_cpu_iowait;
ccb2fe209   Venkatesh Pallipadi   [CPUFREQ] Remove ...
76
  	cputime64_t prev_cpu_wall;
808009131   venkatesh.pallipadi@intel.com   [CPUFREQ][6/6] cp...
77
  	cputime64_t prev_cpu_nice;
32ee8c3e4   Dave Jones   [CPUFREQ] Lots of...
78
  	struct cpufreq_policy *cur_policy;
2b03f891a   Dave Jones   [CPUFREQ] checkpa...
79
  	struct delayed_work work;
05ca0350e   Alexey Starikovskiy   [CPUFREQ][2/2] on...
80
81
82
83
  	struct cpufreq_frequency_table *freq_table;
  	unsigned int freq_lo;
  	unsigned int freq_lo_jiffies;
  	unsigned int freq_hi_jiffies;
3f78a9f7f   David C Niemi   [CPUFREQ] add sam...
84
  	unsigned int rate_mult;
529af7a14   Venkatesh Pallipadi   [CPUFREQ] ondeman...
85
  	int cpu;
5a75c8282   venkatesh.pallipadi@intel.com   [CPUFREQ] Cleanup...
86
87
88
89
90
91
92
  	unsigned int sample_type:1;
  	/*
  	 * percpu mutex that serializes governor limit change with
  	 * do_dbs_timer invocation. We do not want do_dbs_timer to run
  	 * when user is changing the governor or limits.
  	 */
  	struct mutex timer_mutex;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
93
  };
245b2e70e   Tejun Heo   percpu: clean up ...
94
  static DEFINE_PER_CPU(struct cpu_dbs_info_s, od_cpu_dbs_info);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
95
96
  
  static unsigned int dbs_enable;	/* number of CPUs using this policy */
4ec223d02   Venkatesh Pallipadi   [CPUFREQ] Fix ond...
97
  /*
326c86dea   Thomas Renninger   [CPUFREQ] Remove ...
98
   * dbs_mutex protects dbs_enable in governor start/stop.
4ec223d02   Venkatesh Pallipadi   [CPUFREQ] Fix ond...
99
   */
ffac80e92   Venkatesh Pallipadi   [CPUFREQ] Misc cl...
100
  static DEFINE_MUTEX(dbs_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101

05ca0350e   Alexey Starikovskiy   [CPUFREQ][2/2] on...
102
  static struct dbs_tuners {
32ee8c3e4   Dave Jones   [CPUFREQ] Lots of...
103
  	unsigned int sampling_rate;
32ee8c3e4   Dave Jones   [CPUFREQ] Lots of...
104
  	unsigned int up_threshold;
e9d95bf7e   venkatesh.pallipadi@intel.com   [CPUFREQ][4/6] cp...
105
  	unsigned int down_differential;
32ee8c3e4   Dave Jones   [CPUFREQ] Lots of...
106
  	unsigned int ignore_nice;
3f78a9f7f   David C Niemi   [CPUFREQ] add sam...
107
  	unsigned int sampling_down_factor;
05ca0350e   Alexey Starikovskiy   [CPUFREQ][2/2] on...
108
  	unsigned int powersave_bias;
19379b118   Arjan van de Ven   ondemand: Make th...
109
  	unsigned int io_is_busy;
05ca0350e   Alexey Starikovskiy   [CPUFREQ][2/2] on...
110
  } dbs_tuners_ins = {
32ee8c3e4   Dave Jones   [CPUFREQ] Lots of...
111
  	.up_threshold = DEF_FREQUENCY_UP_THRESHOLD,
3f78a9f7f   David C Niemi   [CPUFREQ] add sam...
112
  	.sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR,
e9d95bf7e   venkatesh.pallipadi@intel.com   [CPUFREQ][4/6] cp...
113
  	.down_differential = DEF_FREQUENCY_DOWN_DIFFERENTIAL,
9cbad61b4   Eric Piel   [PATCH] cpufreq_o...
114
  	.ignore_nice = 0,
05ca0350e   Alexey Starikovskiy   [CPUFREQ][2/2] on...
115
  	.powersave_bias = 0,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
116
  };
3292beb34   Glauber Costa   sched/accounting:...
117
  static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall)
dac1c1a56   Dave Jones   [CPUFREQ] ondeman...
118
  {
3292beb34   Glauber Costa   sched/accounting:...
119
  	u64 idle_time;
612ef28a0   Martin Schwidefsky   Merge branch 'sch...
120
  	u64 cur_wall_time;
3292beb34   Glauber Costa   sched/accounting:...
121
  	u64 busy_time;
ccb2fe209   Venkatesh Pallipadi   [CPUFREQ] Remove ...
122

3430502d3   venkatesh.pallipadi@intel.com   [CPUFREQ][3/6] cp...
123
  	cur_wall_time = jiffies64_to_cputime64(get_jiffies_64());
ccb2fe209   Venkatesh Pallipadi   [CPUFREQ] Remove ...
124

612ef28a0   Martin Schwidefsky   Merge branch 'sch...
125
126
  	busy_time  = kcpustat_cpu(cpu).cpustat[CPUTIME_USER];
  	busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SYSTEM];
3292beb34   Glauber Costa   sched/accounting:...
127
128
129
130
  	busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_IRQ];
  	busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SOFTIRQ];
  	busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_STEAL];
  	busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_NICE];
648616343   Martin Schwidefsky   [S390] cputime: a...
131
132
  
  	idle_time = cur_wall_time - busy_time;
3430502d3   venkatesh.pallipadi@intel.com   [CPUFREQ][3/6] cp...
133
  	if (wall)
3292beb34   Glauber Costa   sched/accounting:...
134
  		*wall = jiffies_to_usecs(cur_wall_time);
3430502d3   venkatesh.pallipadi@intel.com   [CPUFREQ][3/6] cp...
135

3292beb34   Glauber Costa   sched/accounting:...
136
  	return jiffies_to_usecs(idle_time);
dac1c1a56   Dave Jones   [CPUFREQ] ondeman...
137
  }
808009131   venkatesh.pallipadi@intel.com   [CPUFREQ][6/6] cp...
138
139
  static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall)
  {
6beea0cda   Michal Hocko   nohz: Fix update_...
140
  	u64 idle_time = get_cpu_idle_time_us(cpu, NULL);
808009131   venkatesh.pallipadi@intel.com   [CPUFREQ][6/6] cp...
141
142
143
  
  	if (idle_time == -1ULL)
  		return get_cpu_idle_time_jiffy(cpu, wall);
6beea0cda   Michal Hocko   nohz: Fix update_...
144
145
  	else
  		idle_time += get_cpu_iowait_time_us(cpu, wall);
808009131   venkatesh.pallipadi@intel.com   [CPUFREQ][6/6] cp...
146

808009131   venkatesh.pallipadi@intel.com   [CPUFREQ][6/6] cp...
147
148
  	return idle_time;
  }
6b8fcd902   Arjan van de Ven   ondemand: Solve a...
149
150
151
152
153
154
155
156
157
  static inline cputime64_t get_cpu_iowait_time(unsigned int cpu, cputime64_t *wall)
  {
  	u64 iowait_time = get_cpu_iowait_time_us(cpu, wall);
  
  	if (iowait_time == -1ULL)
  		return 0;
  
  	return iowait_time;
  }
05ca0350e   Alexey Starikovskiy   [CPUFREQ][2/2] on...
158
159
160
161
162
  /*
   * Find right freq to be set now with powersave_bias on.
   * Returns the freq_hi to be used right now and will set freq_hi_jiffies,
   * freq_lo, and freq_lo_jiffies in percpu area for averaging freqs.
   */
b5ecf60fe   Adrian Bunk   [CPUFREQ] make dr...
163
164
165
  static unsigned int powersave_bias_target(struct cpufreq_policy *policy,
  					  unsigned int freq_next,
  					  unsigned int relation)
05ca0350e   Alexey Starikovskiy   [CPUFREQ][2/2] on...
166
167
168
169
170
  {
  	unsigned int freq_req, freq_reduc, freq_avg;
  	unsigned int freq_hi, freq_lo;
  	unsigned int index = 0;
  	unsigned int jiffies_total, jiffies_hi, jiffies_lo;
245b2e70e   Tejun Heo   percpu: clean up ...
171
172
  	struct cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info,
  						   policy->cpu);
05ca0350e   Alexey Starikovskiy   [CPUFREQ][2/2] on...
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
  
  	if (!dbs_info->freq_table) {
  		dbs_info->freq_lo = 0;
  		dbs_info->freq_lo_jiffies = 0;
  		return freq_next;
  	}
  
  	cpufreq_frequency_table_target(policy, dbs_info->freq_table, freq_next,
  			relation, &index);
  	freq_req = dbs_info->freq_table[index].frequency;
  	freq_reduc = freq_req * dbs_tuners_ins.powersave_bias / 1000;
  	freq_avg = freq_req - freq_reduc;
  
  	/* Find freq bounds for freq_avg in freq_table */
  	index = 0;
  	cpufreq_frequency_table_target(policy, dbs_info->freq_table, freq_avg,
  			CPUFREQ_RELATION_H, &index);
  	freq_lo = dbs_info->freq_table[index].frequency;
  	index = 0;
  	cpufreq_frequency_table_target(policy, dbs_info->freq_table, freq_avg,
  			CPUFREQ_RELATION_L, &index);
  	freq_hi = dbs_info->freq_table[index].frequency;
  
  	/* Find out how long we have to be in hi and lo freqs */
  	if (freq_hi == freq_lo) {
  		dbs_info->freq_lo = 0;
  		dbs_info->freq_lo_jiffies = 0;
  		return freq_lo;
  	}
  	jiffies_total = usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
  	jiffies_hi = (freq_avg - freq_lo) * jiffies_total;
  	jiffies_hi += ((freq_hi - freq_lo) / 2);
  	jiffies_hi /= (freq_hi - freq_lo);
  	jiffies_lo = jiffies_total - jiffies_hi;
  	dbs_info->freq_lo = freq_lo;
  	dbs_info->freq_lo_jiffies = jiffies_lo;
  	dbs_info->freq_hi_jiffies = jiffies_hi;
  	return freq_hi;
  }
5a75c8282   venkatesh.pallipadi@intel.com   [CPUFREQ] Cleanup...
212
213
  static void ondemand_powersave_bias_init_cpu(int cpu)
  {
384be2b18   Tejun Heo   Merge branch 'per...
214
  	struct cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, cpu);
5a75c8282   venkatesh.pallipadi@intel.com   [CPUFREQ] Cleanup...
215
216
217
  	dbs_info->freq_table = cpufreq_frequency_get_table(cpu);
  	dbs_info->freq_lo = 0;
  }
05ca0350e   Alexey Starikovskiy   [CPUFREQ][2/2] on...
218
219
220
221
  static void ondemand_powersave_bias_init(void)
  {
  	int i;
  	for_each_online_cpu(i) {
5a75c8282   venkatesh.pallipadi@intel.com   [CPUFREQ] Cleanup...
222
  		ondemand_powersave_bias_init_cpu(i);
05ca0350e   Alexey Starikovskiy   [CPUFREQ][2/2] on...
223
224
  	}
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
225
  /************************** sysfs interface ************************/
0e625ac15   Thomas Renninger   [CPUFREQ] ondeman...
226

0e625ac15   Thomas Renninger   [CPUFREQ] ondeman...
227
228
  static ssize_t show_sampling_rate_min(struct kobject *kobj,
  				      struct attribute *attr, char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
229
  {
cef9615a8   Thomas Renninger   [CPUFREQ] ondeman...
230
231
  	return sprintf(buf, "%u
  ", min_sampling_rate);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
232
  }
6dad2a296   Borislav Petkov   cpufreq: Unify sy...
233
  define_one_global_ro(sampling_rate_min);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
234
235
236
237
  
  /* cpufreq_ondemand Governor Tunables */
  #define show_one(file_name, object)					\
  static ssize_t show_##file_name						\
0e625ac15   Thomas Renninger   [CPUFREQ] ondeman...
238
  (struct kobject *kobj, struct attribute *attr, char *buf)              \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
239
240
241
242
243
  {									\
  	return sprintf(buf, "%u
  ", dbs_tuners_ins.object);		\
  }
  show_one(sampling_rate, sampling_rate);
19379b118   Arjan van de Ven   ondemand: Make th...
244
  show_one(io_is_busy, io_is_busy);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
245
  show_one(up_threshold, up_threshold);
3f78a9f7f   David C Niemi   [CPUFREQ] add sam...
246
  show_one(sampling_down_factor, sampling_down_factor);
001893cda   Alexander Clouter   [PATCH] cpufreq_c...
247
  show_one(ignore_nice_load, ignore_nice);
05ca0350e   Alexey Starikovskiy   [CPUFREQ][2/2] on...
248
  show_one(powersave_bias, powersave_bias);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
249

0e625ac15   Thomas Renninger   [CPUFREQ] ondeman...
250
251
  static ssize_t store_sampling_rate(struct kobject *a, struct attribute *b,
  				   const char *buf, size_t count)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
252
253
254
  {
  	unsigned int input;
  	int ret;
ffac80e92   Venkatesh Pallipadi   [CPUFREQ] Misc cl...
255
  	ret = sscanf(buf, "%u", &input);
5a75c8282   venkatesh.pallipadi@intel.com   [CPUFREQ] Cleanup...
256
257
  	if (ret != 1)
  		return -EINVAL;
cef9615a8   Thomas Renninger   [CPUFREQ] ondeman...
258
  	dbs_tuners_ins.sampling_rate = max(input, min_sampling_rate);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
259
260
  	return count;
  }
19379b118   Arjan van de Ven   ondemand: Make th...
261
262
263
264
265
266
267
268
269
  static ssize_t store_io_is_busy(struct kobject *a, struct attribute *b,
  				   const char *buf, size_t count)
  {
  	unsigned int input;
  	int ret;
  
  	ret = sscanf(buf, "%u", &input);
  	if (ret != 1)
  		return -EINVAL;
19379b118   Arjan van de Ven   ondemand: Make th...
270
  	dbs_tuners_ins.io_is_busy = !!input;
19379b118   Arjan van de Ven   ondemand: Make th...
271
272
  	return count;
  }
0e625ac15   Thomas Renninger   [CPUFREQ] ondeman...
273
274
  static ssize_t store_up_threshold(struct kobject *a, struct attribute *b,
  				  const char *buf, size_t count)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
275
276
277
  {
  	unsigned int input;
  	int ret;
ffac80e92   Venkatesh Pallipadi   [CPUFREQ] Misc cl...
278
  	ret = sscanf(buf, "%u", &input);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
279

32ee8c3e4   Dave Jones   [CPUFREQ] Lots of...
280
  	if (ret != 1 || input > MAX_FREQUENCY_UP_THRESHOLD ||
c29f14030   Dave Jones   [CPUFREQ] ondeman...
281
  			input < MIN_FREQUENCY_UP_THRESHOLD) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
282
283
  		return -EINVAL;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
284
  	dbs_tuners_ins.up_threshold = input;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
285
286
  	return count;
  }
3f78a9f7f   David C Niemi   [CPUFREQ] add sam...
287
288
289
290
291
292
293
294
295
  static ssize_t store_sampling_down_factor(struct kobject *a,
  			struct attribute *b, const char *buf, size_t count)
  {
  	unsigned int input, j;
  	int ret;
  	ret = sscanf(buf, "%u", &input);
  
  	if (ret != 1 || input > MAX_SAMPLING_DOWN_FACTOR || input < 1)
  		return -EINVAL;
3f78a9f7f   David C Niemi   [CPUFREQ] add sam...
296
297
298
299
300
301
302
303
  	dbs_tuners_ins.sampling_down_factor = input;
  
  	/* Reset down sampling multiplier in case it was active */
  	for_each_online_cpu(j) {
  		struct cpu_dbs_info_s *dbs_info;
  		dbs_info = &per_cpu(od_cpu_dbs_info, j);
  		dbs_info->rate_mult = 1;
  	}
3f78a9f7f   David C Niemi   [CPUFREQ] add sam...
304
305
  	return count;
  }
0e625ac15   Thomas Renninger   [CPUFREQ] ondeman...
306
307
  static ssize_t store_ignore_nice_load(struct kobject *a, struct attribute *b,
  				      const char *buf, size_t count)
3d5ee9e55   Dave Jones   [CPUFREQ] Add sup...
308
309
310
311
312
  {
  	unsigned int input;
  	int ret;
  
  	unsigned int j;
32ee8c3e4   Dave Jones   [CPUFREQ] Lots of...
313

ffac80e92   Venkatesh Pallipadi   [CPUFREQ] Misc cl...
314
  	ret = sscanf(buf, "%u", &input);
2b03f891a   Dave Jones   [CPUFREQ] checkpa...
315
  	if (ret != 1)
3d5ee9e55   Dave Jones   [CPUFREQ] Add sup...
316
  		return -EINVAL;
2b03f891a   Dave Jones   [CPUFREQ] checkpa...
317
  	if (input > 1)
3d5ee9e55   Dave Jones   [CPUFREQ] Add sup...
318
  		input = 1;
32ee8c3e4   Dave Jones   [CPUFREQ] Lots of...
319

2b03f891a   Dave Jones   [CPUFREQ] checkpa...
320
  	if (input == dbs_tuners_ins.ignore_nice) { /* nothing to do */
3d5ee9e55   Dave Jones   [CPUFREQ] Add sup...
321
322
323
  		return count;
  	}
  	dbs_tuners_ins.ignore_nice = input;
ccb2fe209   Venkatesh Pallipadi   [CPUFREQ] Remove ...
324
  	/* we need to re-evaluate prev_cpu_idle */
dac1c1a56   Dave Jones   [CPUFREQ] ondeman...
325
  	for_each_online_cpu(j) {
ccb2fe209   Venkatesh Pallipadi   [CPUFREQ] Remove ...
326
  		struct cpu_dbs_info_s *dbs_info;
245b2e70e   Tejun Heo   percpu: clean up ...
327
  		dbs_info = &per_cpu(od_cpu_dbs_info, j);
3430502d3   venkatesh.pallipadi@intel.com   [CPUFREQ][3/6] cp...
328
329
  		dbs_info->prev_cpu_idle = get_cpu_idle_time(j,
  						&dbs_info->prev_cpu_wall);
1ca3abdb6   Venkatesh Pallipadi   [CPUFREQ] Make ig...
330
  		if (dbs_tuners_ins.ignore_nice)
3292beb34   Glauber Costa   sched/accounting:...
331
  			dbs_info->prev_cpu_nice = kcpustat_cpu(j).cpustat[CPUTIME_NICE];
1ca3abdb6   Venkatesh Pallipadi   [CPUFREQ] Make ig...
332

3d5ee9e55   Dave Jones   [CPUFREQ] Add sup...
333
  	}
3d5ee9e55   Dave Jones   [CPUFREQ] Add sup...
334
335
  	return count;
  }
0e625ac15   Thomas Renninger   [CPUFREQ] ondeman...
336
337
  static ssize_t store_powersave_bias(struct kobject *a, struct attribute *b,
  				    const char *buf, size_t count)
05ca0350e   Alexey Starikovskiy   [CPUFREQ][2/2] on...
338
339
340
341
342
343
344
345
346
347
  {
  	unsigned int input;
  	int ret;
  	ret = sscanf(buf, "%u", &input);
  
  	if (ret != 1)
  		return -EINVAL;
  
  	if (input > 1000)
  		input = 1000;
05ca0350e   Alexey Starikovskiy   [CPUFREQ][2/2] on...
348
349
  	dbs_tuners_ins.powersave_bias = input;
  	ondemand_powersave_bias_init();
05ca0350e   Alexey Starikovskiy   [CPUFREQ][2/2] on...
350
351
  	return count;
  }
6dad2a296   Borislav Petkov   cpufreq: Unify sy...
352
  define_one_global_rw(sampling_rate);
07d77759c   Linus Torvalds   Merge branch 'x86...
353
  define_one_global_rw(io_is_busy);
6dad2a296   Borislav Petkov   cpufreq: Unify sy...
354
  define_one_global_rw(up_threshold);
3f78a9f7f   David C Niemi   [CPUFREQ] add sam...
355
  define_one_global_rw(sampling_down_factor);
6dad2a296   Borislav Petkov   cpufreq: Unify sy...
356
357
  define_one_global_rw(ignore_nice_load);
  define_one_global_rw(powersave_bias);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
358

2b03f891a   Dave Jones   [CPUFREQ] checkpa...
359
  static struct attribute *dbs_attributes[] = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
360
361
  	&sampling_rate_min.attr,
  	&sampling_rate.attr,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
362
  	&up_threshold.attr,
3f78a9f7f   David C Niemi   [CPUFREQ] add sam...
363
  	&sampling_down_factor.attr,
001893cda   Alexander Clouter   [PATCH] cpufreq_c...
364
  	&ignore_nice_load.attr,
05ca0350e   Alexey Starikovskiy   [CPUFREQ][2/2] on...
365
  	&powersave_bias.attr,
19379b118   Arjan van de Ven   ondemand: Make th...
366
  	&io_is_busy.attr,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
367
368
369
370
371
372
373
374
375
  	NULL
  };
  
  static struct attribute_group dbs_attr_group = {
  	.attrs = dbs_attributes,
  	.name = "ondemand",
  };
  
  /************************** sysfs end ************************/
00e299fff   Mike Chan   [CPUFREQ] ondeman...
376
377
378
379
380
381
382
383
384
385
  static void dbs_freq_increase(struct cpufreq_policy *p, unsigned int freq)
  {
  	if (dbs_tuners_ins.powersave_bias)
  		freq = powersave_bias_target(p, freq, CPUFREQ_RELATION_H);
  	else if (p->cur == p->max)
  		return;
  
  	__cpufreq_driver_target(p, freq, dbs_tuners_ins.powersave_bias ?
  			CPUFREQ_RELATION_L : CPUFREQ_RELATION_H);
  }
2f8a835c7   Venkatesh Pallipadi   [CPUFREQ] Make on...
386
  static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
387
  {
c43aa3bd9   venkatesh.pallipadi@intel.com   [CPUFREQ][2/6] cp...
388
  	unsigned int max_load_freq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
389
390
391
  
  	struct cpufreq_policy *policy;
  	unsigned int j;
05ca0350e   Alexey Starikovskiy   [CPUFREQ][2/2] on...
392
  	this_dbs_info->freq_lo = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
393
  	policy = this_dbs_info->cur_policy;
ea4876151   Venki Pallipadi   [CPUFREQ] ondeman...
394

32ee8c3e4   Dave Jones   [CPUFREQ] Lots of...
395
  	/*
c29f14030   Dave Jones   [CPUFREQ] ondeman...
396
397
  	 * Every sampling_rate, we check, if current idle time is less
  	 * than 20% (default), then we try to increase frequency
ccb2fe209   Venkatesh Pallipadi   [CPUFREQ] Remove ...
398
  	 * Every sampling_rate, we look for a the lowest
c29f14030   Dave Jones   [CPUFREQ] ondeman...
399
400
  	 * frequency which can sustain the load while keeping idle time over
  	 * 30%. If such a frequency exist, we try to decrease to this frequency.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
401
  	 *
32ee8c3e4   Dave Jones   [CPUFREQ] Lots of...
402
403
404
  	 * Any frequency increase takes it to the maximum frequency.
  	 * Frequency reduction happens at minimum steps of
  	 * 5% (default) of current frequency
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
405
  	 */
c43aa3bd9   venkatesh.pallipadi@intel.com   [CPUFREQ][2/6] cp...
406
407
  	/* Get Absolute Load - in terms of freq */
  	max_load_freq = 0;
835481d9b   Rusty Russell   cpumask: convert ...
408
  	for_each_cpu(j, policy->cpus) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
409
  		struct cpu_dbs_info_s *j_dbs_info;
6b8fcd902   Arjan van de Ven   ondemand: Solve a...
410
411
  		cputime64_t cur_wall_time, cur_idle_time, cur_iowait_time;
  		unsigned int idle_time, wall_time, iowait_time;
c43aa3bd9   venkatesh.pallipadi@intel.com   [CPUFREQ][2/6] cp...
412
413
  		unsigned int load, load_freq;
  		int freq_avg;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
414

245b2e70e   Tejun Heo   percpu: clean up ...
415
  		j_dbs_info = &per_cpu(od_cpu_dbs_info, j);
3430502d3   venkatesh.pallipadi@intel.com   [CPUFREQ][3/6] cp...
416
417
  
  		cur_idle_time = get_cpu_idle_time(j, &cur_wall_time);
6b8fcd902   Arjan van de Ven   ondemand: Solve a...
418
  		cur_iowait_time = get_cpu_iowait_time(j, &cur_wall_time);
3430502d3   venkatesh.pallipadi@intel.com   [CPUFREQ][3/6] cp...
419

648616343   Martin Schwidefsky   [S390] cputime: a...
420
421
  		wall_time = (unsigned int)
  			(cur_wall_time - j_dbs_info->prev_cpu_wall);
c43aa3bd9   venkatesh.pallipadi@intel.com   [CPUFREQ][2/6] cp...
422
  		j_dbs_info->prev_cpu_wall = cur_wall_time;
648616343   Martin Schwidefsky   [S390] cputime: a...
423
424
  		idle_time = (unsigned int)
  			(cur_idle_time - j_dbs_info->prev_cpu_idle);
c43aa3bd9   venkatesh.pallipadi@intel.com   [CPUFREQ][2/6] cp...
425
  		j_dbs_info->prev_cpu_idle = cur_idle_time;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
426

648616343   Martin Schwidefsky   [S390] cputime: a...
427
428
  		iowait_time = (unsigned int)
  			(cur_iowait_time - j_dbs_info->prev_cpu_iowait);
6b8fcd902   Arjan van de Ven   ondemand: Solve a...
429
  		j_dbs_info->prev_cpu_iowait = cur_iowait_time;
1ca3abdb6   Venkatesh Pallipadi   [CPUFREQ] Make ig...
430
  		if (dbs_tuners_ins.ignore_nice) {
3292beb34   Glauber Costa   sched/accounting:...
431
  			u64 cur_nice;
1ca3abdb6   Venkatesh Pallipadi   [CPUFREQ] Make ig...
432
  			unsigned long cur_nice_jiffies;
3292beb34   Glauber Costa   sched/accounting:...
433
434
  			cur_nice = kcpustat_cpu(j).cpustat[CPUTIME_NICE] -
  					 j_dbs_info->prev_cpu_nice;
1ca3abdb6   Venkatesh Pallipadi   [CPUFREQ] Make ig...
435
436
437
438
439
440
  			/*
  			 * Assumption: nice time between sampling periods will
  			 * be less than 2^32 jiffies for 32 bit sys
  			 */
  			cur_nice_jiffies = (unsigned long)
  					cputime64_to_jiffies64(cur_nice);
3292beb34   Glauber Costa   sched/accounting:...
441
  			j_dbs_info->prev_cpu_nice = kcpustat_cpu(j).cpustat[CPUTIME_NICE];
1ca3abdb6   Venkatesh Pallipadi   [CPUFREQ] Make ig...
442
443
  			idle_time += jiffies_to_usecs(cur_nice_jiffies);
  		}
6b8fcd902   Arjan van de Ven   ondemand: Solve a...
444
445
446
447
448
449
  		/*
  		 * For the purpose of ondemand, waiting for disk IO is an
  		 * indication that you're performance critical, and not that
  		 * the system is actually idle. So subtract the iowait time
  		 * from the cpu idle time.
  		 */
19379b118   Arjan van de Ven   ondemand: Make th...
450
  		if (dbs_tuners_ins.io_is_busy && idle_time >= iowait_time)
6b8fcd902   Arjan van de Ven   ondemand: Solve a...
451
  			idle_time -= iowait_time;
3430502d3   venkatesh.pallipadi@intel.com   [CPUFREQ][3/6] cp...
452
  		if (unlikely(!wall_time || wall_time < idle_time))
c43aa3bd9   venkatesh.pallipadi@intel.com   [CPUFREQ][2/6] cp...
453
  			continue;
c43aa3bd9   venkatesh.pallipadi@intel.com   [CPUFREQ][2/6] cp...
454
455
456
457
458
459
460
461
462
463
  
  		load = 100 * (wall_time - idle_time) / wall_time;
  
  		freq_avg = __cpufreq_driver_getavg(policy, j);
  		if (freq_avg <= 0)
  			freq_avg = policy->cur;
  
  		load_freq = load * freq_avg;
  		if (load_freq > max_load_freq)
  			max_load_freq = load_freq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
464
  	}
ccb2fe209   Venkatesh Pallipadi   [CPUFREQ] Remove ...
465
  	/* Check for frequency increase */
c43aa3bd9   venkatesh.pallipadi@intel.com   [CPUFREQ][2/6] cp...
466
  	if (max_load_freq > dbs_tuners_ins.up_threshold * policy->cur) {
3f78a9f7f   David C Niemi   [CPUFREQ] add sam...
467
468
469
470
  		/* If switching to max speed, apply sampling_down_factor */
  		if (policy->cur < policy->max)
  			this_dbs_info->rate_mult =
  				dbs_tuners_ins.sampling_down_factor;
00e299fff   Mike Chan   [CPUFREQ] ondeman...
471
  		dbs_freq_increase(policy, policy->max);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
472
473
474
475
  		return;
  	}
  
  	/* Check for frequency decrease */
c29f14030   Dave Jones   [CPUFREQ] ondeman...
476
477
478
  	/* if we cannot reduce the frequency anymore, break out early */
  	if (policy->cur == policy->min)
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
479

c29f14030   Dave Jones   [CPUFREQ] ondeman...
480
481
482
483
484
  	/*
  	 * The optimal frequency is the frequency that is the lowest that
  	 * can support the current CPU usage without triggering the up
  	 * policy. To be safe, we focus 10 points under the threshold.
  	 */
e9d95bf7e   venkatesh.pallipadi@intel.com   [CPUFREQ][4/6] cp...
485
486
487
  	if (max_load_freq <
  	    (dbs_tuners_ins.up_threshold - dbs_tuners_ins.down_differential) *
  	     policy->cur) {
c43aa3bd9   venkatesh.pallipadi@intel.com   [CPUFREQ][2/6] cp...
488
  		unsigned int freq_next;
e9d95bf7e   venkatesh.pallipadi@intel.com   [CPUFREQ][4/6] cp...
489
490
491
  		freq_next = max_load_freq /
  				(dbs_tuners_ins.up_threshold -
  				 dbs_tuners_ins.down_differential);
dfde5d62e   Venkatesh Pallipadi   [CPUFREQ][8/8] ac...
492

3f78a9f7f   David C Niemi   [CPUFREQ] add sam...
493
494
  		/* No longer fully busy, reset rate_mult */
  		this_dbs_info->rate_mult = 1;
1dbf58881   Nagananda.Chumbalkar@hp.com   [CPUFREQ] Fix ond...
495
496
  		if (freq_next < policy->min)
  			freq_next = policy->min;
05ca0350e   Alexey Starikovskiy   [CPUFREQ][2/2] on...
497
498
499
500
501
502
503
504
505
  		if (!dbs_tuners_ins.powersave_bias) {
  			__cpufreq_driver_target(policy, freq_next,
  					CPUFREQ_RELATION_L);
  		} else {
  			int freq = powersave_bias_target(policy, freq_next,
  					CPUFREQ_RELATION_L);
  			__cpufreq_driver_target(policy, freq,
  				CPUFREQ_RELATION_L);
  		}
ccb2fe209   Venkatesh Pallipadi   [CPUFREQ] Remove ...
506
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
507
  }
c4028958b   David Howells   WorkStruct: make ...
508
  static void do_dbs_timer(struct work_struct *work)
32ee8c3e4   Dave Jones   [CPUFREQ] Lots of...
509
  {
529af7a14   Venkatesh Pallipadi   [CPUFREQ] ondeman...
510
511
512
513
  	struct cpu_dbs_info_s *dbs_info =
  		container_of(work, struct cpu_dbs_info_s, work.work);
  	unsigned int cpu = dbs_info->cpu;
  	int sample_type = dbs_info->sample_type;
5cb2c3bd0   Vincent Guittot   [CPUFREQ] calcula...
514
  	int delay;
a665df9d5   Jocelyn Falempe   [CPUFREQ] ondeman...
515

5a75c8282   venkatesh.pallipadi@intel.com   [CPUFREQ] Cleanup...
516
  	mutex_lock(&dbs_info->timer_mutex);
56463b78c   Venkatesh Pallipadi   [CPUFREQ] ondeman...
517

05ca0350e   Alexey Starikovskiy   [CPUFREQ][2/2] on...
518
  	/* Common NORMAL_SAMPLE setup */
c4028958b   David Howells   WorkStruct: make ...
519
  	dbs_info->sample_type = DBS_NORMAL_SAMPLE;
05ca0350e   Alexey Starikovskiy   [CPUFREQ][2/2] on...
520
  	if (!dbs_tuners_ins.powersave_bias ||
c4028958b   David Howells   WorkStruct: make ...
521
  	    sample_type == DBS_NORMAL_SAMPLE) {
05ca0350e   Alexey Starikovskiy   [CPUFREQ][2/2] on...
522
  		dbs_check_cpu(dbs_info);
05ca0350e   Alexey Starikovskiy   [CPUFREQ][2/2] on...
523
524
  		if (dbs_info->freq_lo) {
  			/* Setup timer for SUB_SAMPLE */
c4028958b   David Howells   WorkStruct: make ...
525
  			dbs_info->sample_type = DBS_SUB_SAMPLE;
05ca0350e   Alexey Starikovskiy   [CPUFREQ][2/2] on...
526
  			delay = dbs_info->freq_hi_jiffies;
5cb2c3bd0   Vincent Guittot   [CPUFREQ] calcula...
527
528
529
530
531
532
533
534
535
  		} else {
  			/* We want all CPUs to do sampling nearly on
  			 * same jiffy
  			 */
  			delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate
  				* dbs_info->rate_mult);
  
  			if (num_online_cpus() > 1)
  				delay -= jiffies % delay;
05ca0350e   Alexey Starikovskiy   [CPUFREQ][2/2] on...
536
537
538
  		}
  	} else {
  		__cpufreq_driver_target(dbs_info->cur_policy,
2b03f891a   Dave Jones   [CPUFREQ] checkpa...
539
  			dbs_info->freq_lo, CPUFREQ_RELATION_H);
5cb2c3bd0   Vincent Guittot   [CPUFREQ] calcula...
540
  		delay = dbs_info->freq_lo_jiffies;
05ca0350e   Alexey Starikovskiy   [CPUFREQ][2/2] on...
541
  	}
57df5573a   Tejun Heo   cpufreq: use syst...
542
  	schedule_delayed_work_on(cpu, &dbs_info->work, delay);
5a75c8282   venkatesh.pallipadi@intel.com   [CPUFREQ] Cleanup...
543
  	mutex_unlock(&dbs_info->timer_mutex);
32ee8c3e4   Dave Jones   [CPUFREQ] Lots of...
544
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
545

529af7a14   Venkatesh Pallipadi   [CPUFREQ] ondeman...
546
  static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
547
  {
1ce28d6b1   Alexey Starikovskiy   [CPUFREQ][1/2] on...
548
549
  	/* We want all CPUs to do sampling nearly on same jiffy */
  	int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
a665df9d5   Jocelyn Falempe   [CPUFREQ] ondeman...
550
551
552
  
  	if (num_online_cpus() > 1)
  		delay -= jiffies % delay;
2f8a835c7   Venkatesh Pallipadi   [CPUFREQ] Make on...
553

c4028958b   David Howells   WorkStruct: make ...
554
  	dbs_info->sample_type = DBS_NORMAL_SAMPLE;
28287033e   Venki Pallipadi   Add a new deferra...
555
  	INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer);
57df5573a   Tejun Heo   cpufreq: use syst...
556
  	schedule_delayed_work_on(dbs_info->cpu, &dbs_info->work, delay);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
557
  }
2cd7cbdf4   Linus Torvalds   [cpufreq] ondeman...
558
  static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
559
  {
b14893a62   Mathieu Desnoyers   [CPUFREQ] fix tim...
560
  	cancel_delayed_work_sync(&dbs_info->work);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
561
  }
19379b118   Arjan van de Ven   ondemand: Make th...
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
  /*
   * Not all CPUs want IO time to be accounted as busy; this dependson how
   * efficient idling at a higher frequency/voltage is.
   * Pavel Machek says this is not so for various generations of AMD and old
   * Intel systems.
   * Mike Chan (androidlcom) calis this is also not true for ARM.
   * Because of this, whitelist specific known (series) of CPUs by default, and
   * leave all others up to the user.
   */
  static int should_io_be_busy(void)
  {
  #if defined(CONFIG_X86)
  	/*
  	 * For Intel, Core 2 (model 15) andl later have an efficient idle.
  	 */
  	if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
  	    boot_cpu_data.x86 == 6 &&
  	    boot_cpu_data.x86_model >= 15)
  		return 1;
  #endif
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
584
585
586
587
588
589
  static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
  				   unsigned int event)
  {
  	unsigned int cpu = policy->cpu;
  	struct cpu_dbs_info_s *this_dbs_info;
  	unsigned int j;
914f7c31b   Jeff Garzik   [CPUFREQ] handle ...
590
  	int rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
591

245b2e70e   Tejun Heo   percpu: clean up ...
592
  	this_dbs_info = &per_cpu(od_cpu_dbs_info, cpu);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
593
594
595
  
  	switch (event) {
  	case CPUFREQ_GOV_START:
ffac80e92   Venkatesh Pallipadi   [CPUFREQ] Misc cl...
596
  		if ((!cpu_online(cpu)) || (!policy->cur))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
597
  			return -EINVAL;
3fc54d37a   Andrew Morton   [CPUFREQ] Convert...
598
  		mutex_lock(&dbs_mutex);
914f7c31b   Jeff Garzik   [CPUFREQ] handle ...
599

5a75c8282   venkatesh.pallipadi@intel.com   [CPUFREQ] Cleanup...
600
  		dbs_enable++;
835481d9b   Rusty Russell   cpumask: convert ...
601
  		for_each_cpu(j, policy->cpus) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
602
  			struct cpu_dbs_info_s *j_dbs_info;
245b2e70e   Tejun Heo   percpu: clean up ...
603
  			j_dbs_info = &per_cpu(od_cpu_dbs_info, j);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
604
  			j_dbs_info->cur_policy = policy;
32ee8c3e4   Dave Jones   [CPUFREQ] Lots of...
605

3430502d3   venkatesh.pallipadi@intel.com   [CPUFREQ][3/6] cp...
606
607
  			j_dbs_info->prev_cpu_idle = get_cpu_idle_time(j,
  						&j_dbs_info->prev_cpu_wall);
3292beb34   Glauber Costa   sched/accounting:...
608
  			if (dbs_tuners_ins.ignore_nice)
1ca3abdb6   Venkatesh Pallipadi   [CPUFREQ] Make ig...
609
  				j_dbs_info->prev_cpu_nice =
3292beb34   Glauber Costa   sched/accounting:...
610
  						kcpustat_cpu(j).cpustat[CPUTIME_NICE];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
611
  		}
529af7a14   Venkatesh Pallipadi   [CPUFREQ] ondeman...
612
  		this_dbs_info->cpu = cpu;
3f78a9f7f   David C Niemi   [CPUFREQ] add sam...
613
  		this_dbs_info->rate_mult = 1;
5a75c8282   venkatesh.pallipadi@intel.com   [CPUFREQ] Cleanup...
614
  		ondemand_powersave_bias_init_cpu(cpu);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
615
616
617
618
619
620
  		/*
  		 * Start the timerschedule work, when this governor
  		 * is used for first time
  		 */
  		if (dbs_enable == 1) {
  			unsigned int latency;
0e625ac15   Thomas Renninger   [CPUFREQ] ondeman...
621
622
623
624
625
626
627
  
  			rc = sysfs_create_group(cpufreq_global_kobject,
  						&dbs_attr_group);
  			if (rc) {
  				mutex_unlock(&dbs_mutex);
  				return rc;
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
628
  			/* policy latency is in nS. Convert it to uS first */
df8b59be0   Dave Jones   [CPUFREQ] Avoid t...
629
630
631
  			latency = policy->cpuinfo.transition_latency / 1000;
  			if (latency == 0)
  				latency = 1;
cef9615a8   Thomas Renninger   [CPUFREQ] ondeman...
632
633
634
635
636
637
  			/* Bring kernel and HW constraints together */
  			min_sampling_rate = max(min_sampling_rate,
  					MIN_LATENCY_MULTIPLIER * latency);
  			dbs_tuners_ins.sampling_rate =
  				max(min_sampling_rate,
  				    latency * LATENCY_MULTIPLIER);
19379b118   Arjan van de Ven   ondemand: Make th...
638
  			dbs_tuners_ins.io_is_busy = should_io_be_busy();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
639
  		}
3fc54d37a   Andrew Morton   [CPUFREQ] Convert...
640
  		mutex_unlock(&dbs_mutex);
7d26e2d5e   venkatesh.pallipadi@intel.com   [CPUFREQ] Elimina...
641

0e625ac15   Thomas Renninger   [CPUFREQ] ondeman...
642
  		mutex_init(&this_dbs_info->timer_mutex);
7d26e2d5e   venkatesh.pallipadi@intel.com   [CPUFREQ] Elimina...
643
  		dbs_timer_init(this_dbs_info);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
644
645
646
  		break;
  
  	case CPUFREQ_GOV_STOP:
2cd7cbdf4   Linus Torvalds   [cpufreq] ondeman...
647
  		dbs_timer_exit(this_dbs_info);
7d26e2d5e   venkatesh.pallipadi@intel.com   [CPUFREQ] Elimina...
648
649
  
  		mutex_lock(&dbs_mutex);
5a75c8282   venkatesh.pallipadi@intel.com   [CPUFREQ] Cleanup...
650
  		mutex_destroy(&this_dbs_info->timer_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
651
  		dbs_enable--;
3fc54d37a   Andrew Morton   [CPUFREQ] Convert...
652
  		mutex_unlock(&dbs_mutex);
0e625ac15   Thomas Renninger   [CPUFREQ] ondeman...
653
654
655
  		if (!dbs_enable)
  			sysfs_remove_group(cpufreq_global_kobject,
  					   &dbs_attr_group);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
656
657
658
659
  
  		break;
  
  	case CPUFREQ_GOV_LIMITS:
5a75c8282   venkatesh.pallipadi@intel.com   [CPUFREQ] Cleanup...
660
  		mutex_lock(&this_dbs_info->timer_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
661
  		if (policy->max < this_dbs_info->cur_policy->cur)
ffac80e92   Venkatesh Pallipadi   [CPUFREQ] Misc cl...
662
  			__cpufreq_driver_target(this_dbs_info->cur_policy,
2b03f891a   Dave Jones   [CPUFREQ] checkpa...
663
  				policy->max, CPUFREQ_RELATION_H);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
664
  		else if (policy->min > this_dbs_info->cur_policy->cur)
ffac80e92   Venkatesh Pallipadi   [CPUFREQ] Misc cl...
665
  			__cpufreq_driver_target(this_dbs_info->cur_policy,
2b03f891a   Dave Jones   [CPUFREQ] checkpa...
666
  				policy->min, CPUFREQ_RELATION_L);
5a75c8282   venkatesh.pallipadi@intel.com   [CPUFREQ] Cleanup...
667
  		mutex_unlock(&this_dbs_info->timer_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
668
669
670
671
  		break;
  	}
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
672
673
  static int __init cpufreq_gov_dbs_init(void)
  {
4f6e6b9f9   Andrea Righi   [CPUFREQ] Fix BUG...
674
675
  	u64 idle_time;
  	int cpu = get_cpu();
808009131   venkatesh.pallipadi@intel.com   [CPUFREQ][6/6] cp...
676

21f2e3c86   Kamalesh Babulal   [CPUFREQ] Remove ...
677
  	idle_time = get_cpu_idle_time_us(cpu, NULL);
4f6e6b9f9   Andrea Righi   [CPUFREQ] Fix BUG...
678
  	put_cpu();
808009131   venkatesh.pallipadi@intel.com   [CPUFREQ][6/6] cp...
679
680
681
682
683
  	if (idle_time != -1ULL) {
  		/* Idle micro accounting is supported. Use finer thresholds */
  		dbs_tuners_ins.up_threshold = MICRO_FREQUENCY_UP_THRESHOLD;
  		dbs_tuners_ins.down_differential =
  					MICRO_FREQUENCY_DOWN_DIFFERENTIAL;
cef9615a8   Thomas Renninger   [CPUFREQ] ondeman...
684
  		/*
bd74b32b7   Paul Bolle   Fix documentation...
685
  		 * In nohz/micro accounting case we set the minimum frequency
cef9615a8   Thomas Renninger   [CPUFREQ] ondeman...
686
687
688
689
690
691
692
693
  		 * not depending on HZ, but fixed (very low). The deferred
  		 * timer might skip some samples if idle/sleeping as needed.
  		*/
  		min_sampling_rate = MICRO_FREQUENCY_MIN_SAMPLE_RATE;
  	} else {
  		/* For correct statistics, we need 10 ticks for each measure */
  		min_sampling_rate =
  			MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(10);
808009131   venkatesh.pallipadi@intel.com   [CPUFREQ][6/6] cp...
694
  	}
888a794ca   Akinobu Mita   [CPUFREQ] add err...
695

57df5573a   Tejun Heo   cpufreq: use syst...
696
  	return cpufreq_register_governor(&cpufreq_gov_ondemand);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
697
698
699
700
  }
  
  static void __exit cpufreq_gov_dbs_exit(void)
  {
1c2562459   Thomas Renninger   [CPUFREQ] allow o...
701
  	cpufreq_unregister_governor(&cpufreq_gov_ondemand);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
702
  }
ffac80e92   Venkatesh Pallipadi   [CPUFREQ] Misc cl...
703
704
705
  MODULE_AUTHOR("Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>");
  MODULE_AUTHOR("Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>");
  MODULE_DESCRIPTION("'cpufreq_ondemand' - A dynamic cpufreq governor for "
2b03f891a   Dave Jones   [CPUFREQ] checkpa...
706
  	"Low Latency Frequency Transition capable processors");
ffac80e92   Venkatesh Pallipadi   [CPUFREQ] Misc cl...
707
  MODULE_LICENSE("GPL");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
708

6915719b3   Johannes Weiner   cpufreq: Initiali...
709
710
711
  #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND
  fs_initcall(cpufreq_gov_dbs_init);
  #else
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
712
  module_init(cpufreq_gov_dbs_init);
6915719b3   Johannes Weiner   cpufreq: Initiali...
713
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
714
  module_exit(cpufreq_gov_dbs_exit);