cpufreq: stats: replace the global lock with atomic

We want to reduce the lock contention so replace the global lock with
atomic.

bug: 127722781
Change-Id: I08ed3d55bf6bf17f31f4017c82c998fb513bad3e
Signed-off-by: Kyle Lin <kylelin@google.com>
Signed-off-by: Danny Lin <danny@kdrag0n.dev>
This commit is contained in:
Kyle Lin 2019-03-20 00:00:28 +08:00 committed by spakkkk
parent e3dc7d8199
commit 9ba5b76315

View File

@ -14,15 +14,13 @@
#include <linux/module.h>
#include <linux/slab.h>
static DEFINE_SPINLOCK(cpufreq_stats_lock);
struct cpufreq_stats {
unsigned int total_trans;
unsigned long long last_time;
atomic64_t last_time;
unsigned int max_state;
unsigned int state_num;
unsigned int last_index;
u64 *time_in_state;
atomic64_t *time_in_state;
unsigned int *freq_table;
unsigned int *trans_table;
};
@ -30,21 +28,19 @@ struct cpufreq_stats {
static void cpufreq_stats_update(struct cpufreq_stats *stats)
{
unsigned long long cur_time = get_jiffies_64();
unsigned long flags;
unsigned long long time = cur_time;
spin_lock_irqsave(&cpufreq_stats_lock, flags);
stats->time_in_state[stats->last_index] += cur_time - stats->last_time;
stats->last_time = cur_time;
spin_unlock_irqrestore(&cpufreq_stats_lock, flags);
time = atomic64_xchg(&stats->last_time, time);
atomic64_add(cur_time - time, &stats->time_in_state[stats->last_index]);
}
static void cpufreq_stats_clear_table(struct cpufreq_stats *stats)
{
unsigned int count = stats->max_state;
memset(stats->time_in_state, 0, count * sizeof(u64));
memset(stats->time_in_state, 0, count * sizeof(atomic64_t));
memset(stats->trans_table, 0, count * count * sizeof(int));
stats->last_time = get_jiffies_64();
atomic64_set(&stats->last_time, get_jiffies_64());
stats->total_trans = 0;
}
@ -63,7 +59,8 @@ static ssize_t show_time_in_state(struct cpufreq_policy *policy, char *buf)
for (i = 0; i < stats->state_num; i++) {
len += sprintf(buf + len, "%u %llu\n", stats->freq_table[i],
(unsigned long long)
jiffies_64_to_clock_t(stats->time_in_state[i]));
jiffies_64_to_clock_t(atomic64_read(
&stats->time_in_state[i])));
}
return len;
}
@ -181,7 +178,7 @@ void cpufreq_stats_create_table(struct cpufreq_policy *policy)
if (!stats)
return;
alloc_size = count * sizeof(int) + count * sizeof(u64);
alloc_size = count * sizeof(int) + count * sizeof(atomic64_t);
alloc_size += count * count * sizeof(int);
@ -202,7 +199,7 @@ void cpufreq_stats_create_table(struct cpufreq_policy *policy)
stats->freq_table[i++] = pos->frequency;
stats->state_num = i;
stats->last_time = get_jiffies_64();
atomic64_set(&stats->last_time, get_jiffies_64());
stats->last_index = freq_table_get_index(stats, policy->cur);
policy->stats = stats;