All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stephen Boyd <sboyd@codeaurora.org>
To: John Stultz <john.stultz@linaro.org>
Cc: Russell King <linux@arm.linux.org.uk>,
	linux-arm-msm@vger.kernel.org, Will Deacon <will.deacon@arm.com>,
	linux-kernel@vger.kernel.org,
	Christopher Covington <cov@codeaurora.org>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	linux-arm-kernel@lists.infradead.org
Subject: [PATCH v4 02/17] sched_clock: Use seqcount instead of rolling our own
Date: Thu, 18 Jul 2013 16:21:15 -0700	[thread overview]
Message-ID: <1374189690-10810-3-git-send-email-sboyd@codeaurora.org> (raw)
In-Reply-To: <1374189690-10810-1-git-send-email-sboyd@codeaurora.org>

We're going to increase the cyc value to 64 bits in the near
future. Doing that is going to break the custom seqcount
implementation in the sched_clock code because 64 bit numbers
aren't guaranteed to be atomic. Replace the cyc_copy with a
seqcount to avoid this problem.

Cc: Russell King <linux@arm.linux.org.uk>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 kernel/time/sched_clock.c | 27 ++++++++-------------------
 1 file changed, 8 insertions(+), 19 deletions(-)

diff --git a/kernel/time/sched_clock.c b/kernel/time/sched_clock.c
index a326f27..396f7b9 100644
--- a/kernel/time/sched_clock.c
+++ b/kernel/time/sched_clock.c
@@ -14,11 +14,12 @@
 #include <linux/syscore_ops.h>
 #include <linux/timer.h>
 #include <linux/sched_clock.h>
+#include <linux/seqlock.h>
 
 struct clock_data {
 	u64 epoch_ns;
 	u32 epoch_cyc;
-	u32 epoch_cyc_copy;
+	seqcount_t seq;
 	unsigned long rate;
 	u32 mult;
 	u32 shift;
@@ -54,23 +55,16 @@ static unsigned long long notrace sched_clock_32(void)
 	u64 epoch_ns;
 	u32 epoch_cyc;
 	u32 cyc;
+	unsigned long seq;
 
 	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
-	 * epoch_cyc_copy in strict order, and read them in strict order.
-	 * If epoch_cyc and epoch_cyc_copy are not equal, then we're in
-	 * the middle of an update, and we should repeat the load.
-	 */
 	do {
+		seq = read_seqcount_begin(&cd.seq);
 		epoch_cyc = cd.epoch_cyc;
-		smp_rmb();
 		epoch_ns = cd.epoch_ns;
-		smp_rmb();
-	} while (epoch_cyc != cd.epoch_cyc_copy);
+	} while (read_seqcount_retry(&cd.seq, seq));
 
 	cyc = read_sched_clock();
 	cyc = (cyc - epoch_cyc) & sched_clock_mask;
@@ -90,16 +84,12 @@ static void notrace update_sched_clock(void)
 	ns = cd.epoch_ns +
 		cyc_to_ns((cyc - cd.epoch_cyc) & sched_clock_mask,
 			  cd.mult, cd.shift);
-	/*
-	 * Write epoch_cyc and epoch_ns in a way that the update is
-	 * detectable in cyc_to_fixed_sched_clock().
-	 */
+
 	raw_local_irq_save(flags);
-	cd.epoch_cyc_copy = cyc;
-	smp_wmb();
+	write_seqcount_begin(&cd.seq);
 	cd.epoch_ns = ns;
-	smp_wmb();
 	cd.epoch_cyc = cyc;
+	write_seqcount_end(&cd.seq);
 	raw_local_irq_restore(flags);
 }
 
@@ -195,7 +185,6 @@ static int sched_clock_suspend(void)
 static void sched_clock_resume(void)
 {
 	cd.epoch_cyc = read_sched_clock();
-	cd.epoch_cyc_copy = cd.epoch_cyc;
 	cd.suspended = false;
 }
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

WARNING: multiple messages have this Message-ID (diff)
From: Stephen Boyd <sboyd@codeaurora.org>
To: John Stultz <john.stultz@linaro.org>
Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	Thomas Gleixner <tglx@linutronix.de>,
	Russell King <linux@arm.linux.org.uk>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Will Deacon <will.deacon@arm.com>,
	Christopher Covington <cov@codeaurora.org>
Subject: [PATCH v4 02/17] sched_clock: Use seqcount instead of rolling our own
Date: Thu, 18 Jul 2013 16:21:15 -0700	[thread overview]
Message-ID: <1374189690-10810-3-git-send-email-sboyd@codeaurora.org> (raw)
In-Reply-To: <1374189690-10810-1-git-send-email-sboyd@codeaurora.org>

We're going to increase the cyc value to 64 bits in the near
future. Doing that is going to break the custom seqcount
implementation in the sched_clock code because 64 bit numbers
aren't guaranteed to be atomic. Replace the cyc_copy with a
seqcount to avoid this problem.

Cc: Russell King <linux@arm.linux.org.uk>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 kernel/time/sched_clock.c | 27 ++++++++-------------------
 1 file changed, 8 insertions(+), 19 deletions(-)

diff --git a/kernel/time/sched_clock.c b/kernel/time/sched_clock.c
index a326f27..396f7b9 100644
--- a/kernel/time/sched_clock.c
+++ b/kernel/time/sched_clock.c
@@ -14,11 +14,12 @@
 #include <linux/syscore_ops.h>
 #include <linux/timer.h>
 #include <linux/sched_clock.h>
+#include <linux/seqlock.h>
 
 struct clock_data {
 	u64 epoch_ns;
 	u32 epoch_cyc;
-	u32 epoch_cyc_copy;
+	seqcount_t seq;
 	unsigned long rate;
 	u32 mult;
 	u32 shift;
@@ -54,23 +55,16 @@ static unsigned long long notrace sched_clock_32(void)
 	u64 epoch_ns;
 	u32 epoch_cyc;
 	u32 cyc;
+	unsigned long seq;
 
 	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
-	 * epoch_cyc_copy in strict order, and read them in strict order.
-	 * If epoch_cyc and epoch_cyc_copy are not equal, then we're in
-	 * the middle of an update, and we should repeat the load.
-	 */
 	do {
+		seq = read_seqcount_begin(&cd.seq);
 		epoch_cyc = cd.epoch_cyc;
-		smp_rmb();
 		epoch_ns = cd.epoch_ns;
-		smp_rmb();
-	} while (epoch_cyc != cd.epoch_cyc_copy);
+	} while (read_seqcount_retry(&cd.seq, seq));
 
 	cyc = read_sched_clock();
 	cyc = (cyc - epoch_cyc) & sched_clock_mask;
@@ -90,16 +84,12 @@ static void notrace update_sched_clock(void)
 	ns = cd.epoch_ns +
 		cyc_to_ns((cyc - cd.epoch_cyc) & sched_clock_mask,
 			  cd.mult, cd.shift);
-	/*
-	 * Write epoch_cyc and epoch_ns in a way that the update is
-	 * detectable in cyc_to_fixed_sched_clock().
-	 */
+
 	raw_local_irq_save(flags);
-	cd.epoch_cyc_copy = cyc;
-	smp_wmb();
+	write_seqcount_begin(&cd.seq);
 	cd.epoch_ns = ns;
-	smp_wmb();
 	cd.epoch_cyc = cyc;
+	write_seqcount_end(&cd.seq);
 	raw_local_irq_restore(flags);
 }
 
@@ -195,7 +185,6 @@ static int sched_clock_suspend(void)
 static void sched_clock_resume(void)
 {
 	cd.epoch_cyc = read_sched_clock();
-	cd.epoch_cyc_copy = cd.epoch_cyc;
 	cd.suspended = false;
 }
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation


WARNING: multiple messages have this Message-ID (diff)
From: sboyd@codeaurora.org (Stephen Boyd)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v4 02/17] sched_clock: Use seqcount instead of rolling our own
Date: Thu, 18 Jul 2013 16:21:15 -0700	[thread overview]
Message-ID: <1374189690-10810-3-git-send-email-sboyd@codeaurora.org> (raw)
In-Reply-To: <1374189690-10810-1-git-send-email-sboyd@codeaurora.org>

We're going to increase the cyc value to 64 bits in the near
future. Doing that is going to break the custom seqcount
implementation in the sched_clock code because 64 bit numbers
aren't guaranteed to be atomic. Replace the cyc_copy with a
seqcount to avoid this problem.

Cc: Russell King <linux@arm.linux.org.uk>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 kernel/time/sched_clock.c | 27 ++++++++-------------------
 1 file changed, 8 insertions(+), 19 deletions(-)

diff --git a/kernel/time/sched_clock.c b/kernel/time/sched_clock.c
index a326f27..396f7b9 100644
--- a/kernel/time/sched_clock.c
+++ b/kernel/time/sched_clock.c
@@ -14,11 +14,12 @@
 #include <linux/syscore_ops.h>
 #include <linux/timer.h>
 #include <linux/sched_clock.h>
+#include <linux/seqlock.h>
 
 struct clock_data {
 	u64 epoch_ns;
 	u32 epoch_cyc;
-	u32 epoch_cyc_copy;
+	seqcount_t seq;
 	unsigned long rate;
 	u32 mult;
 	u32 shift;
@@ -54,23 +55,16 @@ static unsigned long long notrace sched_clock_32(void)
 	u64 epoch_ns;
 	u32 epoch_cyc;
 	u32 cyc;
+	unsigned long seq;
 
 	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
-	 * epoch_cyc_copy in strict order, and read them in strict order.
-	 * If epoch_cyc and epoch_cyc_copy are not equal, then we're in
-	 * the middle of an update, and we should repeat the load.
-	 */
 	do {
+		seq = read_seqcount_begin(&cd.seq);
 		epoch_cyc = cd.epoch_cyc;
-		smp_rmb();
 		epoch_ns = cd.epoch_ns;
-		smp_rmb();
-	} while (epoch_cyc != cd.epoch_cyc_copy);
+	} while (read_seqcount_retry(&cd.seq, seq));
 
 	cyc = read_sched_clock();
 	cyc = (cyc - epoch_cyc) & sched_clock_mask;
@@ -90,16 +84,12 @@ static void notrace update_sched_clock(void)
 	ns = cd.epoch_ns +
 		cyc_to_ns((cyc - cd.epoch_cyc) & sched_clock_mask,
 			  cd.mult, cd.shift);
-	/*
-	 * Write epoch_cyc and epoch_ns in a way that the update is
-	 * detectable in cyc_to_fixed_sched_clock().
-	 */
+
 	raw_local_irq_save(flags);
-	cd.epoch_cyc_copy = cyc;
-	smp_wmb();
+	write_seqcount_begin(&cd.seq);
 	cd.epoch_ns = ns;
-	smp_wmb();
 	cd.epoch_cyc = cyc;
+	write_seqcount_end(&cd.seq);
 	raw_local_irq_restore(flags);
 }
 
@@ -195,7 +185,6 @@ static int sched_clock_suspend(void)
 static void sched_clock_resume(void)
 {
 	cd.epoch_cyc = read_sched_clock();
-	cd.epoch_cyc_copy = cd.epoch_cyc;
 	cd.suspended = false;
 }
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

  parent reply	other threads:[~2013-07-18 23:21 UTC|newest]

Thread overview: 119+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-07-18 23:21 [PATCH v4 00/17] 64-bit friendly generic sched_clock() Stephen Boyd
2013-07-18 23:21 ` Stephen Boyd
2013-07-18 23:21 ` [PATCH v4 01/17] clocksource: Extract max nsec calculation into separate function Stephen Boyd
2013-07-18 23:21   ` Stephen Boyd
2013-07-18 23:21 ` Stephen Boyd [this message]
2013-07-18 23:21   ` [PATCH v4 02/17] sched_clock: Use seqcount instead of rolling our own Stephen Boyd
2013-07-18 23:21   ` Stephen Boyd
2013-07-19  9:03   ` Will Deacon
2013-07-19  9:03     ` Will Deacon
2013-07-19  9:03     ` Will Deacon
2013-07-19 14:20     ` Nicolas Pitre
2013-07-19 14:20       ` Nicolas Pitre
2013-07-19 14:20       ` Nicolas Pitre
2013-07-19 14:27       ` Russell King - ARM Linux
2013-07-19 14:27         ` Russell King - ARM Linux
2013-07-19 14:27         ` Russell King - ARM Linux
2013-07-18 23:21 ` [PATCH v4 03/17] sched_clock: Use an hrtimer instead of timer Stephen Boyd
2013-07-18 23:21   ` Stephen Boyd
2013-07-22 18:21   ` John Stultz
2013-07-22 18:21     ` John Stultz
2013-07-22 18:45     ` Stephen Boyd
2013-07-22 18:45       ` Stephen Boyd
2013-07-22 18:58       ` Stephen Boyd
2013-07-22 18:58         ` Stephen Boyd
2013-07-22 19:07         ` Russell King - ARM Linux
2013-07-22 19:07           ` Russell King - ARM Linux
2013-07-22 20:48         ` John Stultz
2013-07-22 20:48           ` John Stultz
2013-07-22 20:50           ` Stephen Boyd
2013-07-22 20:50             ` Stephen Boyd
2013-07-18 23:21 ` [PATCH v4 04/17] sched_clock: Add support for >32 bit sched_clock Stephen Boyd
2013-07-18 23:21   ` Stephen Boyd
2013-07-18 23:21   ` Stephen Boyd
2013-07-19  9:23   ` Baruch Siach
2013-07-19  9:23     ` Baruch Siach
2013-07-19 16:29     ` Stephen Boyd
2013-07-19 16:29       ` Stephen Boyd
2013-07-19 16:29       ` Stephen Boyd
2013-07-18 23:21 ` [PATCH v4 05/17] arch_timer: Move to generic sched_clock framework Stephen Boyd
2013-07-18 23:21   ` Stephen Boyd
2013-10-02 17:44   ` Will Deacon
2013-10-02 17:44     ` Will Deacon
2013-10-02 17:44     ` Will Deacon
2013-10-14 18:44   ` Kevin Hilman
2013-10-14 18:44     ` Kevin Hilman
2013-10-14 18:55     ` Stephen Boyd
2013-10-14 18:55       ` Stephen Boyd
2013-10-14 20:14       ` Kevin Hilman
2013-10-14 20:14         ` Kevin Hilman
2013-10-14 20:18         ` John Stultz
2013-10-14 20:18           ` John Stultz
2013-10-14 20:18           ` John Stultz
2013-10-14 20:14       ` John Stultz
2013-10-14 20:14         ` John Stultz
2013-10-14 20:14         ` John Stultz
2013-07-18 23:21 ` [PATCH v4 06/17] sched_clock: Remove sched_clock_func() hook Stephen Boyd
2013-07-18 23:21   ` Stephen Boyd
2013-07-18 23:21 ` [PATCH v4 07/17] clocksource: bcm2835: Switch to sched_clock_register() Stephen Boyd
2013-07-18 23:21   ` Stephen Boyd
2013-07-19 19:34   ` Stephen Warren
2013-07-19 19:34     ` Stephen Warren
2013-07-30 10:04   ` Daniel Lezcano
2013-07-30 10:04     ` Daniel Lezcano
2013-07-30 16:12     ` John Stultz
2013-07-30 16:12       ` John Stultz
2013-07-18 23:21 ` [PATCH v4 08/17] ocksource: dbx500-prcmu: " Stephen Boyd
2013-07-18 23:21   ` Stephen Boyd
2013-07-19  0:18   ` Stephen Boyd
2013-07-19  0:18     ` Stephen Boyd
2013-07-18 23:21 ` [PATCH v4 09/17] clocksource: dw_apb_timer_of: " Stephen Boyd
2013-07-18 23:21   ` Stephen Boyd
2013-07-18 23:21 ` [PATCH v4 10/17] clocksource: mxs_timer: " Stephen Boyd
2013-07-18 23:21   ` Stephen Boyd
2013-07-22  8:10   ` Shawn Guo
2013-07-22  8:10     ` Shawn Guo
2013-07-22  8:10     ` Shawn Guo
2013-07-22 16:23     ` Stephen Boyd
2013-07-22 16:23       ` Stephen Boyd
2013-07-18 23:21 ` [PATCH v4 11/17] clocksource: nomadik: " Stephen Boyd
2013-07-18 23:21   ` Stephen Boyd
2013-07-18 23:21 ` [PATCH v4 12/17] clocksource: samsung_pwm_timer: " Stephen Boyd
2013-07-18 23:21   ` Stephen Boyd
2013-07-18 23:21 ` [PATCH v4 13/17] clocksource: tegra: " Stephen Boyd
2013-07-18 23:21   ` Stephen Boyd
2013-07-19 19:34   ` Stephen Warren
2013-07-19 19:34     ` Stephen Warren
2013-07-18 23:21 ` [PATCH v4 14/17] clocksource: time-armada-370-xp: " Stephen Boyd
2013-07-18 23:21   ` Stephen Boyd
2013-08-06  9:04   ` Gregory CLEMENT
2013-08-06  9:04     ` Gregory CLEMENT
2013-07-18 23:21 ` [PATCH v4 15/17] clocksource: sirf: Switch to sched_clock_register() and use 64 bits Stephen Boyd
2013-07-18 23:21   ` Stephen Boyd
2013-07-18 23:21 ` [PATCH v4 16/17] clocksource: vf_pit_timer: Switch to sched_clock_register() Stephen Boyd
2013-07-18 23:21   ` Stephen Boyd
2013-07-18 23:21 ` [PATCH v4 17/17] sched_clock: Deprecate setup_sched_clock() Stephen Boyd
2013-07-18 23:21   ` Stephen Boyd
2013-07-18 23:59 ` [PATCH v4 00/17] 64-bit friendly generic sched_clock() John Stultz
2013-07-18 23:59   ` John Stultz
2013-07-19  0:23   ` Stephen Boyd
2013-07-19  0:23     ` Stephen Boyd
2013-10-02 17:47   ` Will Deacon
2013-10-02 17:47     ` Will Deacon
2013-10-02 17:47     ` Will Deacon
2013-10-02 18:02     ` John Stultz
2013-10-02 18:02       ` John Stultz
2013-10-02 18:02       ` John Stultz
2013-10-02 18:13       ` Will Deacon
2013-10-02 18:13         ` Will Deacon
2013-10-02 18:13         ` Will Deacon
2013-07-20 20:51 ` Linus Walleij
2013-07-20 20:51   ` Linus Walleij
2013-07-20 20:51   ` Linus Walleij
2013-07-22 16:24   ` Stephen Boyd
2013-07-22 16:24     ` Stephen Boyd
2013-07-22 16:24     ` Stephen Boyd
2013-07-22 17:07 ` John Stultz
2013-07-22 17:07   ` John Stultz
2013-07-24 14:44 ` Christopher Covington
2013-07-24 14:44   ` Christopher Covington

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=1374189690-10810-3-git-send-email-sboyd@codeaurora.org \
    --to=sboyd@codeaurora.org \
    --cc=catalin.marinas@arm.com \
    --cc=cov@codeaurora.org \
    --cc=john.stultz@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@arm.linux.org.uk \
    --cc=tglx@linutronix.de \
    --cc=will.deacon@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 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.