Skip to content

Commit

Permalink
PM: EM: Change debugfs configuration to use runtime EM table data
Browse files Browse the repository at this point in the history
Dump the runtime EM table values which can be modified in time. In order
to do that allocate chunk of debug memory which can be later freed
automatically thanks to devm_kcalloc().

This design can handle the fact that the EM table memory can change
after EM update, so debug code cannot use the pointer from initialization
phase.

Reviewed-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
Tested-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
Signed-off-by: Lukasz Luba <lukasz.luba@arm.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  • Loading branch information
Lukasz Luba authored and Rafael J. Wysocki committed Feb 8, 2024
1 parent 9f5fb51 commit 09417e6
Showing 1 changed file with 59 additions and 8 deletions.
67 changes: 59 additions & 8 deletions kernel/power/energy_model.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,65 @@ static bool _is_cpu_device(struct device *dev)
#ifdef CONFIG_DEBUG_FS
static struct dentry *rootdir;

static void em_debug_create_ps(struct em_perf_state *ps, struct dentry *pd)
struct em_dbg_info {
struct em_perf_domain *pd;
int ps_id;
};

#define DEFINE_EM_DBG_SHOW(name, fname) \
static int em_debug_##fname##_show(struct seq_file *s, void *unused) \
{ \
struct em_dbg_info *em_dbg = s->private; \
struct em_perf_state *table; \
unsigned long val; \
\
rcu_read_lock(); \
table = em_perf_state_from_pd(em_dbg->pd); \
val = table[em_dbg->ps_id].name; \
rcu_read_unlock(); \
\
seq_printf(s, "%lu\n", val); \
return 0; \
} \
DEFINE_SHOW_ATTRIBUTE(em_debug_##fname)

DEFINE_EM_DBG_SHOW(frequency, frequency);
DEFINE_EM_DBG_SHOW(power, power);
DEFINE_EM_DBG_SHOW(cost, cost);
DEFINE_EM_DBG_SHOW(performance, performance);
DEFINE_EM_DBG_SHOW(flags, inefficiency);

static void em_debug_create_ps(struct em_perf_domain *em_pd,
struct em_dbg_info *em_dbg, int i,
struct dentry *pd)
{
struct em_perf_state *table;
unsigned long freq;
struct dentry *d;
char name[24];

snprintf(name, sizeof(name), "ps:%lu", ps->frequency);
em_dbg[i].pd = em_pd;
em_dbg[i].ps_id = i;

rcu_read_lock();
table = em_perf_state_from_pd(em_pd);
freq = table[i].frequency;
rcu_read_unlock();

snprintf(name, sizeof(name), "ps:%lu", freq);

/* Create per-ps directory */
d = debugfs_create_dir(name, pd);
debugfs_create_ulong("frequency", 0444, d, &ps->frequency);
debugfs_create_ulong("power", 0444, d, &ps->power);
debugfs_create_ulong("cost", 0444, d, &ps->cost);
debugfs_create_ulong("performance", 0444, d, &ps->performance);
debugfs_create_ulong("inefficient", 0444, d, &ps->flags);
debugfs_create_file("frequency", 0444, d, &em_dbg[i],
&em_debug_frequency_fops);
debugfs_create_file("power", 0444, d, &em_dbg[i],
&em_debug_power_fops);
debugfs_create_file("cost", 0444, d, &em_dbg[i],
&em_debug_cost_fops);
debugfs_create_file("performance", 0444, d, &em_dbg[i],
&em_debug_performance_fops);
debugfs_create_file("inefficient", 0444, d, &em_dbg[i],
&em_debug_inefficiency_fops);
}

static int em_debug_cpus_show(struct seq_file *s, void *unused)
Expand All @@ -73,6 +118,7 @@ DEFINE_SHOW_ATTRIBUTE(em_debug_flags);

static void em_debug_create_pd(struct device *dev)
{
struct em_dbg_info *em_dbg;
struct dentry *d;
int i;

Expand All @@ -86,9 +132,14 @@ static void em_debug_create_pd(struct device *dev)
debugfs_create_file("flags", 0444, d, dev->em_pd,
&em_debug_flags_fops);

em_dbg = devm_kcalloc(dev, dev->em_pd->nr_perf_states,
sizeof(*em_dbg), GFP_KERNEL);
if (!em_dbg)
return;

/* Create a sub-directory for each performance state */
for (i = 0; i < dev->em_pd->nr_perf_states; i++)
em_debug_create_ps(&dev->em_pd->table[i], d);
em_debug_create_ps(dev->em_pd, em_dbg, i, d);

}

Expand Down

0 comments on commit 09417e6

Please sign in to comment.