From: Viresh Kumar <viresh.kumar@linaro.org>
To: Rafael Wysocki <rjw@rjwysocki.net>,
Viresh Kumar <viresh.kumar@linaro.org>
Cc: linux-pm@vger.kernel.org,
Vincent Guittot <vincent.guittot@linaro.org>,
Lukasz Luba <lukasz.luba@arm.com>,
cristian.marussi@arm.com, sudeep.holla@arm.com,
linux-kernel@vger.kernel.org
Subject: [PATCH V2 1/4] cpufreq: stats: Defer stats update to cpufreq_stats_record_transition()
Date: Wed, 16 Sep 2020 12:15:28 +0530 [thread overview]
Message-ID: <31999d801bfb4d8063dc1ceec1234b6b80b4ae68.1600238586.git.viresh.kumar@linaro.org> (raw)
In-Reply-To: <cover.1600238586.git.viresh.kumar@linaro.org>
In order to prepare for lock-less stats update, add support to defer any
updates to it until cpufreq_stats_record_transition() is called.
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
drivers/cpufreq/cpufreq_stats.c | 75 ++++++++++++++++++++++++---------
1 file changed, 56 insertions(+), 19 deletions(-)
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
index 94d959a8e954..3e7eee29ee86 100644
--- a/drivers/cpufreq/cpufreq_stats.c
+++ b/drivers/cpufreq/cpufreq_stats.c
@@ -22,17 +22,22 @@ struct cpufreq_stats {
spinlock_t lock;
unsigned int *freq_table;
unsigned int *trans_table;
+
+ /* Deferred reset */
+ unsigned int reset_pending;
+ unsigned long long reset_time;
};
-static void cpufreq_stats_update(struct cpufreq_stats *stats)
+static void cpufreq_stats_update(struct cpufreq_stats *stats,
+ unsigned long long time)
{
unsigned long long cur_time = get_jiffies_64();
- stats->time_in_state[stats->last_index] += cur_time - stats->last_time;
+ stats->time_in_state[stats->last_index] += cur_time - time;
stats->last_time = cur_time;
}
-static void cpufreq_stats_clear_table(struct cpufreq_stats *stats)
+static void cpufreq_stats_reset_table(struct cpufreq_stats *stats)
{
unsigned int count = stats->max_state;
@@ -41,42 +46,67 @@ static void cpufreq_stats_clear_table(struct cpufreq_stats *stats)
memset(stats->trans_table, 0, count * count * sizeof(int));
stats->last_time = get_jiffies_64();
stats->total_trans = 0;
+
+ /* Adjust for the time elapsed since reset was requested */
+ WRITE_ONCE(stats->reset_pending, 0);
+ cpufreq_stats_update(stats, stats->reset_time);
spin_unlock(&stats->lock);
}
static ssize_t show_total_trans(struct cpufreq_policy *policy, char *buf)
{
- return sprintf(buf, "%d\n", policy->stats->total_trans);
+ struct cpufreq_stats *stats = policy->stats;
+
+ if (READ_ONCE(stats->reset_pending))
+ return sprintf(buf, "%d\n", 0);
+ else
+ return sprintf(buf, "%d\n", stats->total_trans);
}
cpufreq_freq_attr_ro(total_trans);
static ssize_t show_time_in_state(struct cpufreq_policy *policy, char *buf)
{
struct cpufreq_stats *stats = policy->stats;
+ bool pending = READ_ONCE(stats->reset_pending);
+ unsigned long long time;
ssize_t len = 0;
int i;
if (policy->fast_switch_enabled)
return 0;
- spin_lock(&stats->lock);
- cpufreq_stats_update(stats);
- spin_unlock(&stats->lock);
-
for (i = 0; i < stats->state_num; i++) {
+ if (pending) {
+ if (i == stats->last_index)
+ time = get_jiffies_64() - stats->reset_time;
+ else
+ time = 0;
+ } else {
+ time = stats->time_in_state[i];
+ if (i == stats->last_index)
+ time += get_jiffies_64() - stats->last_time;
+ }
+
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(time));
}
return len;
}
cpufreq_freq_attr_ro(time_in_state);
+/* We don't care what is written to the attribute */
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);
+ struct cpufreq_stats *stats = policy->stats;
+
+ /*
+ * Defer resetting of stats to cpufreq_stats_record_transition() to
+ * avoid races.
+ */
+ WRITE_ONCE(stats->reset_pending, 1);
+ stats->reset_time = get_jiffies_64();
+
return count;
}
cpufreq_freq_attr_wo(reset);
@@ -84,8 +114,9 @@ cpufreq_freq_attr_wo(reset);
static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf)
{
struct cpufreq_stats *stats = policy->stats;
+ bool pending = READ_ONCE(stats->reset_pending);
ssize_t len = 0;
- int i, j;
+ int i, j, count;
if (policy->fast_switch_enabled)
return 0;
@@ -113,8 +144,13 @@ static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf)
for (j = 0; j < stats->state_num; j++) {
if (len >= PAGE_SIZE)
break;
- len += scnprintf(buf + len, PAGE_SIZE - len, "%9u ",
- stats->trans_table[i*stats->max_state+j]);
+
+ if (pending)
+ count = 0;
+ else
+ count = stats->trans_table[i * stats->max_state + j];
+
+ len += scnprintf(buf + len, PAGE_SIZE - len, "%9u ", count);
}
if (len >= PAGE_SIZE)
break;
@@ -228,10 +264,11 @@ void cpufreq_stats_record_transition(struct cpufreq_policy *policy,
struct cpufreq_stats *stats = policy->stats;
int old_index, new_index;
- if (!stats) {
- pr_debug("%s: No stats found\n", __func__);
+ if (!stats)
return;
- }
+
+ if (READ_ONCE(stats->reset_pending))
+ cpufreq_stats_reset_table(stats);
old_index = stats->last_index;
new_index = freq_table_get_index(stats, new_freq);
@@ -241,7 +278,7 @@ void cpufreq_stats_record_transition(struct cpufreq_policy *policy,
return;
spin_lock(&stats->lock);
- cpufreq_stats_update(stats);
+ cpufreq_stats_update(stats, stats->last_time);
stats->last_index = new_index;
stats->trans_table[old_index * stats->max_state + new_index]++;
--
2.25.0.rc1.19.g042ed3e048af
next prev parent reply other threads:[~2020-09-16 6:45 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-09-16 6:45 [PATCH V2 0/4] cpufreq: Record stats with fast-switching Viresh Kumar
2020-09-16 6:45 ` Viresh Kumar [this message]
2020-09-23 13:48 ` [PATCH V2 1/4] cpufreq: stats: Defer stats update to cpufreq_stats_record_transition() Rafael J. Wysocki
2020-09-24 9:25 ` Lukasz Luba
2020-09-24 10:24 ` Rafael J. Wysocki
2020-09-24 11:00 ` Lukasz Luba
2020-09-24 11:07 ` Rafael J. Wysocki
2020-09-24 12:39 ` Viresh Kumar
2020-09-24 16:10 ` Lukasz Luba
2020-09-25 6:09 ` Viresh Kumar
2020-09-25 8:10 ` Lukasz Luba
2020-09-24 13:15 ` Viresh Kumar
2020-09-25 10:04 ` Rafael J. Wysocki
2020-09-25 10:58 ` Viresh Kumar
2020-09-25 11:09 ` Rafael J. Wysocki
2020-09-25 11:26 ` Viresh Kumar
2020-09-25 8:21 ` Lukasz Luba
2020-09-25 10:46 ` Viresh Kumar
2020-09-16 6:45 ` [PATCH V2 2/4] cpufreq: stats: Remove locking Viresh Kumar
2020-09-16 6:45 ` [PATCH V2 3/4] cpufreq: stats: Enable stats for fast-switch as well Viresh Kumar
2020-09-23 15:14 ` Rafael J. Wysocki
2020-09-23 15:17 ` Rafael J. Wysocki
2020-09-16 6:45 ` [PATCH V2 4/4] cpufreq: Move traces and update to policy->cur to cpufreq core Viresh Kumar
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=31999d801bfb4d8063dc1ceec1234b6b80b4ae68.1600238586.git.viresh.kumar@linaro.org \
--to=viresh.kumar@linaro.org \
--cc=cristian.marussi@arm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=lukasz.luba@arm.com \
--cc=rjw@rjwysocki.net \
--cc=sudeep.holla@arm.com \
--cc=vincent.guittot@linaro.org \
/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).