diff options
author | Viresh Kumar <viresh.kumar@linaro.org> | 2015-01-13 01:04:00 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2015-01-23 17:06:44 -0500 |
commit | a9aaf2915ee265735c28b764551d084e61a694e0 (patch) | |
tree | 68706030add04688b679a9ab0fa7c46afd945ec5 /drivers/cpufreq | |
parent | 2aba0c1bae564a59fc38c407abf7985f9e347cc4 (diff) |
cpufreq: stats: get rid of per-cpu cpufreq_stats_table
All CPUs sharing a cpufreq policy share stats too. For this reason,
add a stats pointer to struct cpufreq_policy and drop per-CPU variable
cpufreq_stats_table used for accessing cpufreq stats so as to reduce
code complexity.
Reviewed-by: Prarit Bhargava <prarit@redhat.com>
Signed-off-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_stats.c | 62 |
1 files changed, 29 insertions, 33 deletions
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index 6c234f548601..3792b2e2f4a8 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c | |||
@@ -31,8 +31,6 @@ struct cpufreq_stats { | |||
31 | #endif | 31 | #endif |
32 | }; | 32 | }; |
33 | 33 | ||
34 | static DEFINE_PER_CPU(struct cpufreq_stats *, cpufreq_stats_table); | ||
35 | |||
36 | static int cpufreq_stats_update(struct cpufreq_stats *stat) | 34 | static int cpufreq_stats_update(struct cpufreq_stats *stat) |
37 | { | 35 | { |
38 | unsigned long long cur_time = get_jiffies_64(); | 36 | unsigned long long cur_time = get_jiffies_64(); |
@@ -48,20 +46,15 @@ static int cpufreq_stats_update(struct cpufreq_stats *stat) | |||
48 | 46 | ||
49 | static ssize_t show_total_trans(struct cpufreq_policy *policy, char *buf) | 47 | static ssize_t show_total_trans(struct cpufreq_policy *policy, char *buf) |
50 | { | 48 | { |
51 | struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, policy->cpu); | 49 | return sprintf(buf, "%d\n", policy->stats->total_trans); |
52 | if (!stat) | ||
53 | return 0; | ||
54 | return sprintf(buf, "%d\n", | ||
55 | per_cpu(cpufreq_stats_table, stat->cpu)->total_trans); | ||
56 | } | 50 | } |
57 | 51 | ||
58 | static ssize_t show_time_in_state(struct cpufreq_policy *policy, char *buf) | 52 | static ssize_t show_time_in_state(struct cpufreq_policy *policy, char *buf) |
59 | { | 53 | { |
54 | struct cpufreq_stats *stat = policy->stats; | ||
60 | ssize_t len = 0; | 55 | ssize_t len = 0; |
61 | int i; | 56 | int i; |
62 | struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, policy->cpu); | 57 | |
63 | if (!stat) | ||
64 | return 0; | ||
65 | cpufreq_stats_update(stat); | 58 | cpufreq_stats_update(stat); |
66 | for (i = 0; i < stat->state_num; i++) { | 59 | for (i = 0; i < stat->state_num; i++) { |
67 | len += sprintf(buf + len, "%u %llu\n", stat->freq_table[i], | 60 | len += sprintf(buf + len, "%u %llu\n", stat->freq_table[i], |
@@ -74,12 +67,10 @@ static ssize_t show_time_in_state(struct cpufreq_policy *policy, char *buf) | |||
74 | #ifdef CONFIG_CPU_FREQ_STAT_DETAILS | 67 | #ifdef CONFIG_CPU_FREQ_STAT_DETAILS |
75 | static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf) | 68 | static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf) |
76 | { | 69 | { |
70 | struct cpufreq_stats *stat = policy->stats; | ||
77 | ssize_t len = 0; | 71 | ssize_t len = 0; |
78 | int i, j; | 72 | int i, j; |
79 | 73 | ||
80 | struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, policy->cpu); | ||
81 | if (!stat) | ||
82 | return 0; | ||
83 | cpufreq_stats_update(stat); | 74 | cpufreq_stats_update(stat); |
84 | len += snprintf(buf + len, PAGE_SIZE - len, " From : To\n"); | 75 | len += snprintf(buf + len, PAGE_SIZE - len, " From : To\n"); |
85 | len += snprintf(buf + len, PAGE_SIZE - len, " : "); | 76 | len += snprintf(buf + len, PAGE_SIZE - len, " : "); |
@@ -145,8 +136,9 @@ static int freq_table_get_index(struct cpufreq_stats *stat, unsigned int freq) | |||
145 | 136 | ||
146 | static void __cpufreq_stats_free_table(struct cpufreq_policy *policy) | 137 | static void __cpufreq_stats_free_table(struct cpufreq_policy *policy) |
147 | { | 138 | { |
148 | struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, policy->cpu); | 139 | struct cpufreq_stats *stat = policy->stats; |
149 | 140 | ||
141 | /* Already freed */ | ||
150 | if (!stat) | 142 | if (!stat) |
151 | return; | 143 | return; |
152 | 144 | ||
@@ -155,7 +147,7 @@ static void __cpufreq_stats_free_table(struct cpufreq_policy *policy) | |||
155 | sysfs_remove_group(&policy->kobj, &stats_attr_group); | 147 | sysfs_remove_group(&policy->kobj, &stats_attr_group); |
156 | kfree(stat->time_in_state); | 148 | kfree(stat->time_in_state); |
157 | kfree(stat); | 149 | kfree(stat); |
158 | per_cpu(cpufreq_stats_table, policy->cpu) = NULL; | 150 | policy->stats = NULL; |
159 | } | 151 | } |
160 | 152 | ||
161 | static void cpufreq_stats_free_table(unsigned int cpu) | 153 | static void cpufreq_stats_free_table(unsigned int cpu) |
@@ -184,7 +176,7 @@ static int __cpufreq_stats_create_table(struct cpufreq_policy *policy) | |||
184 | return 0; | 176 | return 0; |
185 | 177 | ||
186 | /* stats already initialized */ | 178 | /* stats already initialized */ |
187 | if (per_cpu(cpufreq_stats_table, cpu)) | 179 | if (policy->stats) |
188 | return -EEXIST; | 180 | return -EEXIST; |
189 | 181 | ||
190 | stat = kzalloc(sizeof(*stat), GFP_KERNEL); | 182 | stat = kzalloc(sizeof(*stat), GFP_KERNEL); |
@@ -196,7 +188,7 @@ static int __cpufreq_stats_create_table(struct cpufreq_policy *policy) | |||
196 | goto error_out; | 188 | goto error_out; |
197 | 189 | ||
198 | stat->cpu = cpu; | 190 | stat->cpu = cpu; |
199 | per_cpu(cpufreq_stats_table, cpu) = stat; | 191 | policy->stats = stat; |
200 | 192 | ||
201 | cpufreq_for_each_valid_entry(pos, table) | 193 | cpufreq_for_each_valid_entry(pos, table) |
202 | count++; | 194 | count++; |
@@ -231,7 +223,7 @@ error_alloc: | |||
231 | sysfs_remove_group(&policy->kobj, &stats_attr_group); | 223 | sysfs_remove_group(&policy->kobj, &stats_attr_group); |
232 | error_out: | 224 | error_out: |
233 | kfree(stat); | 225 | kfree(stat); |
234 | per_cpu(cpufreq_stats_table, cpu) = NULL; | 226 | policy->stats = NULL; |
235 | return ret; | 227 | return ret; |
236 | } | 228 | } |
237 | 229 | ||
@@ -254,15 +246,7 @@ static void cpufreq_stats_create_table(unsigned int cpu) | |||
254 | 246 | ||
255 | static void cpufreq_stats_update_policy_cpu(struct cpufreq_policy *policy) | 247 | static void cpufreq_stats_update_policy_cpu(struct cpufreq_policy *policy) |
256 | { | 248 | { |
257 | struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, | 249 | policy->stats->cpu = policy->cpu; |
258 | policy->last_cpu); | ||
259 | |||
260 | pr_debug("Updating stats_table for new_cpu %u from last_cpu %u\n", | ||
261 | policy->cpu, policy->last_cpu); | ||
262 | per_cpu(cpufreq_stats_table, policy->cpu) = per_cpu(cpufreq_stats_table, | ||
263 | policy->last_cpu); | ||
264 | per_cpu(cpufreq_stats_table, policy->last_cpu) = NULL; | ||
265 | stat->cpu = policy->cpu; | ||
266 | } | 250 | } |
267 | 251 | ||
268 | static int cpufreq_stat_notifier_policy(struct notifier_block *nb, | 252 | static int cpufreq_stat_notifier_policy(struct notifier_block *nb, |
@@ -288,27 +272,36 @@ static int cpufreq_stat_notifier_trans(struct notifier_block *nb, | |||
288 | unsigned long val, void *data) | 272 | unsigned long val, void *data) |
289 | { | 273 | { |
290 | struct cpufreq_freqs *freq = data; | 274 | struct cpufreq_freqs *freq = data; |
275 | struct cpufreq_policy *policy = cpufreq_cpu_get(freq->cpu); | ||
291 | struct cpufreq_stats *stat; | 276 | struct cpufreq_stats *stat; |
292 | int old_index, new_index; | 277 | int old_index, new_index; |
293 | 278 | ||
294 | if (val != CPUFREQ_POSTCHANGE) | 279 | if (!policy) { |
280 | pr_err("%s: No policy found\n", __func__); | ||
295 | return 0; | 281 | return 0; |
282 | } | ||
296 | 283 | ||
297 | stat = per_cpu(cpufreq_stats_table, freq->cpu); | 284 | if (val != CPUFREQ_POSTCHANGE) |
298 | if (!stat) | 285 | goto put_policy; |
299 | return 0; | 286 | |
287 | if (!policy->stats) { | ||
288 | pr_debug("%s: No stats found\n", __func__); | ||
289 | goto put_policy; | ||
290 | } | ||
291 | |||
292 | stat = policy->stats; | ||
300 | 293 | ||
301 | old_index = stat->last_index; | 294 | old_index = stat->last_index; |
302 | new_index = freq_table_get_index(stat, freq->new); | 295 | new_index = freq_table_get_index(stat, freq->new); |
303 | 296 | ||
304 | /* We can't do stat->time_in_state[-1]= .. */ | 297 | /* We can't do stat->time_in_state[-1]= .. */ |
305 | if (old_index == -1 || new_index == -1) | 298 | if (old_index == -1 || new_index == -1) |
306 | return 0; | 299 | goto put_policy; |
307 | 300 | ||
308 | cpufreq_stats_update(stat); | 301 | cpufreq_stats_update(stat); |
309 | 302 | ||
310 | if (old_index == new_index) | 303 | if (old_index == new_index) |
311 | return 0; | 304 | goto put_policy; |
312 | 305 | ||
313 | spin_lock(&cpufreq_stats_lock); | 306 | spin_lock(&cpufreq_stats_lock); |
314 | stat->last_index = new_index; | 307 | stat->last_index = new_index; |
@@ -317,6 +310,9 @@ static int cpufreq_stat_notifier_trans(struct notifier_block *nb, | |||
317 | #endif | 310 | #endif |
318 | stat->total_trans++; | 311 | stat->total_trans++; |
319 | spin_unlock(&cpufreq_stats_lock); | 312 | spin_unlock(&cpufreq_stats_lock); |
313 | |||
314 | put_policy: | ||
315 | cpufreq_cpu_put(policy); | ||
320 | return 0; | 316 | return 0; |
321 | } | 317 | } |
322 | 318 | ||