drivers: cpufreq: backport cpufreq_times from Exynos9820

This commit is contained in:
Anan Jaser 2023-03-29 22:26:02 +04:00 committed by Mustafa Gökmen
parent dd6694e199
commit 632f7f6b83
No known key found for this signature in database
GPG key ID: 3204D8100CFF21ED
5 changed files with 51 additions and 40 deletions

View file

@ -37,14 +37,6 @@ config CPU_FREQ_STAT
If in doubt, say N.
config CPU_FREQ_STAT_DETAILS
bool "CPU frequency transition statistics details"
depends on CPU_FREQ_STAT
help
Show detailed CPU frequency transition table in sysfs.
If in doubt, say N.
config CPU_FREQ_TIMES
bool "CPU frequency time-in-state statistics"
help

View file

@ -24,9 +24,7 @@ struct cpufreq_stats {
unsigned int last_index;
u64 *time_in_state;
unsigned int *freq_table;
#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
unsigned int *trans_table;
#endif
};
static int cpufreq_stats_update(struct cpufreq_stats *stats)
@ -40,6 +38,16 @@ static int cpufreq_stats_update(struct cpufreq_stats *stats)
return 0;
}
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->trans_table, 0, count * count * sizeof(int));
stats->last_time = get_jiffies_64();
stats->total_trans = 0;
}
static ssize_t show_total_trans(struct cpufreq_policy *policy, char *buf)
{
return sprintf(buf, "%d\n", policy->stats->total_trans);
@ -63,7 +71,14 @@ static ssize_t show_time_in_state(struct cpufreq_policy *policy, char *buf)
return len;
}
#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
static ssize_t store_reset(struct cpufreq_policy *policy, const char *buf,
size_t count)
{
/* We don't care what is written to the attribute. */
cpufreq_stats_clear_table(policy->stats);
return count;
}
static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf)
{
struct cpufreq_stats *stats = policy->stats;
@ -108,20 +123,19 @@ static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf)
return len;
}
cpufreq_freq_attr_ro(trans_table);
#endif
cpufreq_freq_attr_ro(total_trans);
cpufreq_freq_attr_ro(time_in_state);
cpufreq_freq_attr_wo(reset);
static struct attribute *default_attrs[] = {
&total_trans.attr,
&time_in_state.attr,
#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
&reset.attr,
&trans_table.attr,
#endif
NULL
};
static struct attribute_group stats_attr_group = {
static const struct attribute_group stats_attr_group = {
.attrs = default_attrs,
.name = "stats"
};
@ -156,11 +170,10 @@ void cpufreq_stats_create_table(struct cpufreq_policy *policy)
unsigned int i = 0, count = 0, ret = -ENOMEM;
struct cpufreq_stats *stats;
unsigned int alloc_size;
struct cpufreq_frequency_table *pos, *table;
struct cpufreq_frequency_table *pos;
/* We need cpufreq table for creating stats table */
table = policy->freq_table;
if (unlikely(!table))
count = cpufreq_table_count_valid_entries(policy);
if (!count)
return;
/* stats already initialized */
@ -171,15 +184,9 @@ void cpufreq_stats_create_table(struct cpufreq_policy *policy)
if (!stats)
return;
/* Find total allocation size */
cpufreq_for_each_valid_entry(pos, table)
count++;
alloc_size = count * sizeof(int) + count * sizeof(u64);
#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
alloc_size += count * count * sizeof(int);
#endif
/* Allocate memory for time_in_state/freq_table/trans_table in one go */
stats->time_in_state = kzalloc(alloc_size, GFP_KERNEL);
@ -188,14 +195,12 @@ void cpufreq_stats_create_table(struct cpufreq_policy *policy)
stats->freq_table = (unsigned int *)(stats->time_in_state + count);
#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
stats->trans_table = stats->freq_table + count;
#endif
stats->max_state = count;
/* Find valid-unique entries */
cpufreq_for_each_valid_entry(pos, table)
cpufreq_for_each_valid_entry(pos, policy->freq_table)
if (freq_table_get_index(stats, pos->frequency) == -1)
stats->freq_table[i++] = pos->frequency;
@ -236,8 +241,6 @@ void cpufreq_stats_record_transition(struct cpufreq_policy *policy,
cpufreq_stats_update(stats);
stats->last_index = new_index;
#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
stats->trans_table[old_index * stats->max_state + new_index]++;
#endif
stats->total_trans++;
}

View file

@ -15,9 +15,9 @@
#include <linux/cpufreq.h>
#include <linux/cpufreq_times.h>
#include <linux/cputime.h>
#include <linux/hashtable.h>
#include <linux/init.h>
#include <linux/jiffies.h>
#include <linux/proc_fs.h>
#include <linux/sched.h>
#include <linux/seq_file.h>
@ -155,7 +155,7 @@ static int single_uid_time_in_state_show(struct seq_file *m, void *ptr)
}
for (i = 0; i < uid_entry->max_state; ++i) {
u64 time = cputime_to_clock_t(uid_entry->time_in_state[i]);
u64 time = nsec_to_clock_t(uid_entry->time_in_state[i]);
seq_write(m, &time, sizeof(time));
}
@ -215,8 +215,7 @@ static int uid_time_in_state_seq_show(struct seq_file *m, void *v)
seq_putc(m, ':');
}
for (i = 0; i < uid_entry->max_state; ++i) {
u64 time =
cputime_to_clock_t(uid_entry->time_in_state[i]);
u64 time = nsec_to_clock_t(uid_entry->time_in_state[i]);
seq_put_decimal_ull(m, " ", time);
}
if (uid_entry->max_state)
@ -242,7 +241,7 @@ static int concurrent_time_seq_show(struct seq_file *m, void *v,
seq_putc(m, ':');
for (i = 0; i < num_possible_cpus; ++i) {
u64 time = cputime_to_clock_t(atomic64_read(&times[i]));
u64 time = nsec_to_clock_t(atomic64_read(&times[i]));
seq_put_decimal_ull(m, " ", time);
}
@ -369,7 +368,7 @@ int proc_time_in_state_show(struct seq_file *m, struct pid_namespace *ns,
struct pid *pid, struct task_struct *p)
{
unsigned int cpu, i;
cputime_t cputime;
u64 cputime;
unsigned long flags;
struct cpu_freqs *freqs;
struct cpu_freqs *last_freqs = NULL;
@ -388,14 +387,14 @@ int proc_time_in_state_show(struct seq_file *m, struct pid_namespace *ns,
p->time_in_state)
cputime = p->time_in_state[freqs->offset + i];
seq_printf(m, "%u %lu\n", freqs->freq_table[i],
(unsigned long)cputime_to_clock_t(cputime));
(unsigned long)nsec_to_clock_t(cputime));
}
}
spin_unlock_irqrestore(&task_time_in_state_lock, flags);
return 0;
}
void cpufreq_acct_update_power(struct task_struct *p, cputime_t cputime)
void cpufreq_acct_update_power(struct task_struct *p, u64 cputime)
{
unsigned long flags;
unsigned int state;

View file

@ -238,6 +238,10 @@ __ATTR(_name, _perm, show_##_name, NULL)
static struct freq_attr _name = \
__ATTR(_name, 0644, show_##_name, store_##_name)
#define cpufreq_freq_attr_wo(_name) \
static struct freq_attr _name = \
__ATTR(_name, 0200, NULL, store_##_name)
#define define_one_global_ro(_name) \
static struct kobj_attribute _name = \
__ATTR(_name, 0444, show_##_name, NULL)
@ -891,6 +895,20 @@ static inline int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
return -EINVAL;
}
}
static inline int cpufreq_table_count_valid_entries(const struct cpufreq_policy *policy)
{
struct cpufreq_frequency_table *pos;
int count = 0;
if (unlikely(!policy->freq_table))
return 0;
cpufreq_for_each_valid_entry(pos, policy->freq_table)
count++;
return count;
}
#else
static inline int cpufreq_boost_trigger_state(int state)
{

View file

@ -17,7 +17,6 @@
#define _LINUX_CPUFREQ_TIMES_H
#include <linux/cpufreq.h>
#include <linux/cputime.h>
#include <linux/pid.h>
#ifdef CONFIG_CPU_FREQ_TIMES
@ -26,7 +25,7 @@ void cpufreq_task_times_alloc(struct task_struct *p);
void cpufreq_task_times_exit(struct task_struct *p);
int proc_time_in_state_show(struct seq_file *m, struct pid_namespace *ns,
struct pid *pid, struct task_struct *p);
void cpufreq_acct_update_power(struct task_struct *p, cputime_t cputime);
void cpufreq_acct_update_power(struct task_struct *p, u64 cputime);
void cpufreq_times_create_policy(struct cpufreq_policy *policy);
void cpufreq_times_record_transition(struct cpufreq_policy *policy,
unsigned int new_freq);