aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@linaro.org>2015-01-13 01:04:00 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-01-23 17:06:44 -0500
commita9aaf2915ee265735c28b764551d084e61a694e0 (patch)
tree68706030add04688b679a9ab0fa7c46afd945ec5 /drivers/cpufreq
parent2aba0c1bae564a59fc38c407abf7985f9e347cc4 (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.c62
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
34static DEFINE_PER_CPU(struct cpufreq_stats *, cpufreq_stats_table);
35
36static int cpufreq_stats_update(struct cpufreq_stats *stat) 34static 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
49static ssize_t show_total_trans(struct cpufreq_policy *policy, char *buf) 47static 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
58static ssize_t show_time_in_state(struct cpufreq_policy *policy, char *buf) 52static 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
75static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf) 68static 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
146static void __cpufreq_stats_free_table(struct cpufreq_policy *policy) 137static 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
161static void cpufreq_stats_free_table(unsigned int cpu) 153static 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);
232error_out: 224error_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
255static void cpufreq_stats_update_policy_cpu(struct cpufreq_policy *policy) 247static 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
268static int cpufreq_stat_notifier_policy(struct notifier_block *nb, 252static 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
314put_policy:
315 cpufreq_cpu_put(policy);
320 return 0; 316 return 0;
321} 317}
322 318