From: ccross@android.com (Colin Cross)
To: linux-arm-kernel@lists.infradead.org
Subject: [RFC] ARM: sched_clock: update epoch_cyc on resume
Date: Tue, 17 Jul 2012 16:27:51 -0700 [thread overview]
Message-ID: <1342567672-29071-1-git-send-email-ccross@android.com> (raw)
Many clocks that are used to provide sched_clock will reset during
suspend. If read_sched_clock returns 0 after suspend, sched_clock will
appear to jump forward. This patch resets cd.epoch_cyc to the current
value of read_sched_clock during resume, which causes sched_clock() just
after suspend to return the same value as sched_clock() just before
suspend.
In addition, during the window where epoch_ns has been updated before
suspend, but epoch_cyc has not been updated after suspend, it is unknown
whether the clock has reset or not, and sched_clock() could return a
bogus value. Add a suspended flag, and return the pre-suspend epoch_ns
value during this period.
This will have a side effect of causing SoCs that have clocks that
continue to count in suspend to appear to stop counting, reporting the
same sched_clock() value before and after suspend.
Signed-off-by: Colin Cross <ccross@android.com>
---
arch/arm/kernel/sched_clock.c | 13 +++++++++++++
1 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/arch/arm/kernel/sched_clock.c b/arch/arm/kernel/sched_clock.c
index 27d186a..46c7d32 100644
--- a/arch/arm/kernel/sched_clock.c
+++ b/arch/arm/kernel/sched_clock.c
@@ -21,6 +21,7 @@ struct clock_data {
u32 epoch_cyc_copy;
u32 mult;
u32 shift;
+ bool suspended;
};
static void sched_clock_poll(unsigned long wrap_ticks);
@@ -49,6 +50,9 @@ static unsigned long long cyc_to_sched_clock(u32 cyc, u32 mask)
u64 epoch_ns;
u32 epoch_cyc;
+ if (cd.suspended)
+ return cd.epoch_ns;
+
/*
* Load the epoch_cyc and epoch_ns atomically. We do this by
* ensuring that we always write epoch_cyc, epoch_ns and
@@ -169,11 +173,20 @@ void __init sched_clock_postinit(void)
static int sched_clock_suspend(void)
{
sched_clock_poll(sched_clock_timer.data);
+ cd.suspended = true;
return 0;
}
+static void sched_clock_resume(void)
+{
+ cd.epoch_cyc = read_sched_clock();
+ cd.epoch_cyc_copy = cd.epoch_cyc;
+ cd.suspended = false;
+}
+
static struct syscore_ops sched_clock_ops = {
.suspend = sched_clock_suspend,
+ .resume = sched_clock_resume,
};
static int __init sched_clock_syscore_init(void)
--
1.7.7.3
WARNING: multiple messages have this Message-ID (diff)
From: Colin Cross <ccross@android.com>
To: linux-arm-kernel@lists.infradead.org
Cc: Colin Cross <ccross@android.com>,
Russell King <linux@arm.linux.org.uk>,
Linus Walleij <linus.walleij@linaro.org>,
Krzysztof Halasa <khc@pm.waw.pl>, Nicolas Pitre <nico@linaro.org>,
Marc Zyngier <marc.zyngier@arm.com>,
linux-kernel@vger.kernel.org
Subject: [RFC] ARM: sched_clock: update epoch_cyc on resume
Date: Tue, 17 Jul 2012 16:27:51 -0700 [thread overview]
Message-ID: <1342567672-29071-1-git-send-email-ccross@android.com> (raw)
Many clocks that are used to provide sched_clock will reset during
suspend. If read_sched_clock returns 0 after suspend, sched_clock will
appear to jump forward. This patch resets cd.epoch_cyc to the current
value of read_sched_clock during resume, which causes sched_clock() just
after suspend to return the same value as sched_clock() just before
suspend.
In addition, during the window where epoch_ns has been updated before
suspend, but epoch_cyc has not been updated after suspend, it is unknown
whether the clock has reset or not, and sched_clock() could return a
bogus value. Add a suspended flag, and return the pre-suspend epoch_ns
value during this period.
This will have a side effect of causing SoCs that have clocks that
continue to count in suspend to appear to stop counting, reporting the
same sched_clock() value before and after suspend.
Signed-off-by: Colin Cross <ccross@android.com>
---
arch/arm/kernel/sched_clock.c | 13 +++++++++++++
1 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/arch/arm/kernel/sched_clock.c b/arch/arm/kernel/sched_clock.c
index 27d186a..46c7d32 100644
--- a/arch/arm/kernel/sched_clock.c
+++ b/arch/arm/kernel/sched_clock.c
@@ -21,6 +21,7 @@ struct clock_data {
u32 epoch_cyc_copy;
u32 mult;
u32 shift;
+ bool suspended;
};
static void sched_clock_poll(unsigned long wrap_ticks);
@@ -49,6 +50,9 @@ static unsigned long long cyc_to_sched_clock(u32 cyc, u32 mask)
u64 epoch_ns;
u32 epoch_cyc;
+ if (cd.suspended)
+ return cd.epoch_ns;
+
/*
* Load the epoch_cyc and epoch_ns atomically. We do this by
* ensuring that we always write epoch_cyc, epoch_ns and
@@ -169,11 +173,20 @@ void __init sched_clock_postinit(void)
static int sched_clock_suspend(void)
{
sched_clock_poll(sched_clock_timer.data);
+ cd.suspended = true;
return 0;
}
+static void sched_clock_resume(void)
+{
+ cd.epoch_cyc = read_sched_clock();
+ cd.epoch_cyc_copy = cd.epoch_cyc;
+ cd.suspended = false;
+}
+
static struct syscore_ops sched_clock_ops = {
.suspend = sched_clock_suspend,
+ .resume = sched_clock_resume,
};
static int __init sched_clock_syscore_init(void)
--
1.7.7.3
next reply other threads:[~2012-07-17 23:27 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-07-17 23:27 Colin Cross [this message]
2012-07-17 23:27 ` [RFC] ARM: sched_clock: update epoch_cyc on resume Colin Cross
2012-07-23 18:55 ` Linus Walleij
2012-07-23 18:55 ` Linus Walleij
2012-07-23 19:27 ` Colin Cross
2012-07-23 19:27 ` Colin Cross
2012-07-24 0:14 ` Linus Walleij
2012-07-24 0:14 ` Linus Walleij
2012-07-24 0:28 ` Colin Cross
2012-07-24 0:28 ` Colin Cross
2012-07-24 9:16 ` Bedia, Vaibhav
2012-07-24 9:16 ` Bedia, Vaibhav
2012-07-27 22:23 ` Linus Walleij
2012-07-27 22:23 ` Linus Walleij
2012-07-27 22:41 ` Russell King - ARM Linux
2012-07-27 22:41 ` Russell King - ARM Linux
2012-07-30 12:31 ` Bedia, Vaibhav
2012-07-30 12:31 ` Bedia, Vaibhav
2012-07-24 6:43 ` Barry Song
2012-07-24 6:43 ` Barry Song
2012-10-19 23:58 ` Kevin Hilman
2012-10-19 23:58 ` Kevin Hilman
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=1342567672-29071-1-git-send-email-ccross@android.com \
--to=ccross@android.com \
--cc=linux-arm-kernel@lists.infradead.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.