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 | ||
