mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 01:53:29 +02:00
pmdomain: core: Add residency reflection for domain-idlestates to debugfs
For regular cpuidle states we are reflecting over the selected/entered state to see if the sleep-duration meets the residency for the state. The output from the reflection is an "above" value to indicate the number of times the state was too deep and a "below" value for the number of times it was too shallow. Let's implement the similar thing for genpd's domain-idlestates along with genpd's governor and put the information in the genpd's debugfs. Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Link: https://lore.kernel.org/r/20250314100103.1294715-5-ulf.hansson@linaro.org
This commit is contained in:
parent
d0252ba821
commit
0a8a888167
|
|
@ -304,10 +304,40 @@ static void genpd_update_accounting(struct generic_pm_domain *genpd)
|
|||
|
||||
genpd->accounting_time = now;
|
||||
}
|
||||
|
||||
static void genpd_reflect_residency(struct generic_pm_domain *genpd)
|
||||
{
|
||||
struct genpd_governor_data *gd = genpd->gd;
|
||||
struct genpd_power_state *state, *next_state;
|
||||
unsigned int state_idx;
|
||||
s64 sleep_ns, target_ns;
|
||||
|
||||
if (!gd || !gd->reflect_residency)
|
||||
return;
|
||||
|
||||
sleep_ns = ktime_to_ns(ktime_sub(ktime_get(), gd->last_enter));
|
||||
state_idx = genpd->state_idx;
|
||||
state = &genpd->states[state_idx];
|
||||
target_ns = state->power_off_latency_ns + state->residency_ns;
|
||||
|
||||
if (sleep_ns < target_ns) {
|
||||
state->above++;
|
||||
} else if (state_idx < (genpd->state_count -1)) {
|
||||
next_state = &genpd->states[state_idx + 1];
|
||||
target_ns = next_state->power_off_latency_ns +
|
||||
next_state->residency_ns;
|
||||
|
||||
if (sleep_ns >= target_ns)
|
||||
state->below++;
|
||||
}
|
||||
|
||||
gd->reflect_residency = false;
|
||||
}
|
||||
#else
|
||||
static inline void genpd_debug_add(struct generic_pm_domain *genpd) {}
|
||||
static inline void genpd_debug_remove(struct generic_pm_domain *genpd) {}
|
||||
static inline void genpd_update_accounting(struct generic_pm_domain *genpd) {}
|
||||
static inline void genpd_reflect_residency(struct generic_pm_domain *genpd) {}
|
||||
#endif
|
||||
|
||||
static int _genpd_reeval_performance_state(struct generic_pm_domain *genpd,
|
||||
|
|
@ -982,6 +1012,9 @@ static int genpd_power_on(struct generic_pm_domain *genpd, unsigned int depth)
|
|||
if (genpd_status_on(genpd))
|
||||
return 0;
|
||||
|
||||
/* Reflect over the entered idle-states residency for debugfs. */
|
||||
genpd_reflect_residency(genpd);
|
||||
|
||||
/*
|
||||
* The list is guaranteed not to change while the loop below is being
|
||||
* executed, unless one of the parents' .power_on() callbacks fiddles
|
||||
|
|
@ -3517,7 +3550,7 @@ static int idle_states_show(struct seq_file *s, void *data)
|
|||
if (ret)
|
||||
return -ERESTARTSYS;
|
||||
|
||||
seq_puts(s, "State Time Spent(ms) Usage Rejected\n");
|
||||
seq_puts(s, "State Time Spent(ms) Usage Rejected Above Below\n");
|
||||
|
||||
for (i = 0; i < genpd->state_count; i++) {
|
||||
struct genpd_power_state *state = &genpd->states[i];
|
||||
|
|
@ -3537,9 +3570,10 @@ static int idle_states_show(struct seq_file *s, void *data)
|
|||
snprintf(state_name, ARRAY_SIZE(state_name), "S%-13d", i);
|
||||
|
||||
do_div(idle_time, NSEC_PER_MSEC);
|
||||
seq_printf(s, "%-14s %-14llu %-14llu %llu\n",
|
||||
seq_printf(s, "%-14s %-14llu %-10llu %-10llu %-10llu %llu\n",
|
||||
state->name ?: state_name, idle_time,
|
||||
state->usage, state->rejected);
|
||||
state->usage, state->rejected, state->above,
|
||||
state->below);
|
||||
}
|
||||
|
||||
genpd_unlock(genpd);
|
||||
|
|
|
|||
|
|
@ -392,6 +392,8 @@ static bool cpu_power_down_ok(struct dev_pm_domain *pd)
|
|||
if (idle_duration_ns >= (genpd->states[i].residency_ns +
|
||||
genpd->states[i].power_off_latency_ns)) {
|
||||
genpd->state_idx = i;
|
||||
genpd->gd->last_enter = now;
|
||||
genpd->gd->reflect_residency = true;
|
||||
return true;
|
||||
}
|
||||
} while (--i >= 0);
|
||||
|
|
|
|||
|
|
@ -142,6 +142,8 @@ struct genpd_governor_data {
|
|||
bool max_off_time_changed;
|
||||
ktime_t next_wakeup;
|
||||
ktime_t next_hrtimer;
|
||||
ktime_t last_enter;
|
||||
bool reflect_residency;
|
||||
bool cached_power_down_ok;
|
||||
bool cached_power_down_state_idx;
|
||||
};
|
||||
|
|
@ -153,6 +155,8 @@ struct genpd_power_state {
|
|||
s64 residency_ns;
|
||||
u64 usage;
|
||||
u64 rejected;
|
||||
u64 above;
|
||||
u64 below;
|
||||
struct fwnode_handle *fwnode;
|
||||
u64 idle_time;
|
||||
void *data;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user