From: Ulf Hansson <ulf.hansson@linaro.org>
To: "Rafael J . Wysocki" <rafael@kernel.org>,
Sudeep Holla <sudeep.holla@arm.com>,
linux-pm@vger.kernel.org
Cc: Lorenzo Pieralisi <lpieralisi@kernel.org>,
Daniel Lezcano <daniel.lezcano@linaro.org>,
Anup Patel <anup@brainfault.org>,
Ulf Hansson <ulf.hansson@linaro.org>,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
Subject: [PATCH 4/4] pmdomain: core: Add residency reflection for domain-idlestates to debugfs
Date: Fri, 14 Mar 2025 11:00:58 +0100 [thread overview]
Message-ID: <20250314100103.1294715-5-ulf.hansson@linaro.org> (raw)
In-Reply-To: <20250314100103.1294715-1-ulf.hansson@linaro.org>
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>
---
drivers/pmdomain/core.c | 40 ++++++++++++++++++++++++++++++++++---
drivers/pmdomain/governor.c | 2 ++
include/linux/pm_domain.h | 4 ++++
3 files changed, 43 insertions(+), 3 deletions(-)
diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
index c79ef6e3ab85..3327de2f9ed2 100644
--- a/drivers/pmdomain/core.c
+++ b/drivers/pmdomain/core.c
@@ -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);
diff --git a/drivers/pmdomain/governor.c b/drivers/pmdomain/governor.c
index d1a10eeebd16..c1e148657c87 100644
--- a/drivers/pmdomain/governor.c
+++ b/drivers/pmdomain/governor.c
@@ -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);
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index 6e808aeecbcb..0b18160901a2 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -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;
--
2.43.0
prev parent reply other threads:[~2025-03-14 10:12 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-14 10:00 [PATCH 0/4] pmdomain/cpuidle-psci: Improve domain-idlestate statistics Ulf Hansson
2025-03-14 10:00 ` [PATCH 1/4] pmdomain: core: Add genpd helper to correct the usage/rejected counters Ulf Hansson
2025-03-14 10:00 ` [PATCH 2/4] cpuidle: psci: Move the per CPU variable domain_state to a struct Ulf Hansson
2025-03-14 10:00 ` [PATCH 3/4] cpuidle: psci: Correct the domain-idlestate statistics in debugfs Ulf Hansson
2025-03-14 10:00 ` Ulf Hansson [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250314100103.1294715-5-ulf.hansson@linaro.org \
--to=ulf.hansson@linaro.org \
--cc=anup@brainfault.org \
--cc=daniel.lezcano@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=lpieralisi@kernel.org \
--cc=rafael@kernel.org \
--cc=sudeep.holla@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).