linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/3] ARM sched_clock selection enhancements
@ 2013-04-01 20:58 Rob Herring
  2013-04-01 20:58 ` [PATCH v2 1/3] ARM: sched_clock: allow changing to higher frequency counter Rob Herring
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Rob Herring @ 2013-04-01 20:58 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rob Herring <rob.herring@calxeda.com>

In preparation to move more timer initialization to use CLKSRC_OF and
out of the platforms, a way to select the timer used for sched_clock is
needed. This series makes the ARM sched_clock function override-able and
makes the sched_clock setup code prefer higher frequency counters. This
is sufficient at least on ARM Ltd boards to use the 24MHz counter rather
than sp804 and to always use the 64-bit architected timer when present.
This mechanism can be extended to DT properties if needed for any
non-discoverable h/w feature.

Patch 1 is unchanged from the prior version. Patch 2 is completely
rewritten and more simple than the prior version. It simply converts
sched_clock to a function pointer which can be overridden by the
architected timer init. It seems unlikely we will have other 64-bit
timers or not want to use the architected timer.

Rob

Rob Herring (3):
  ARM: sched_clock: allow changing to higher frequency counter
  ARM: make sched_clock just call a function pointer
  ARM: arch_timer: use full 64-bit counter for sched_clock

 arch/arm/include/asm/sched_clock.h |    2 ++
 arch/arm/kernel/arch_timer.c       |   15 ++++++++++-----
 arch/arm/kernel/sched_clock.c      |   15 +++++++++++++--
 3 files changed, 25 insertions(+), 7 deletions(-)

-- 
1.7.10.4

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v2 1/3] ARM: sched_clock: allow changing to higher frequency counter
  2013-04-01 20:58 [PATCH v2 0/3] ARM sched_clock selection enhancements Rob Herring
@ 2013-04-01 20:58 ` Rob Herring
  2013-04-01 20:58 ` [PATCH v2 2/3] ARM: make sched_clock just call a function pointer Rob Herring
  2013-04-01 20:58 ` [PATCH v2 3/3] ARM: arch_timer: use full 64-bit counter for sched_clock Rob Herring
  2 siblings, 0 replies; 5+ messages in thread
From: Rob Herring @ 2013-04-01 20:58 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rob Herring <rob.herring@calxeda.com>

Allow multiple calls to setup_sched_clock and switch to the new counter
if it is higher frequency.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 arch/arm/kernel/sched_clock.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm/kernel/sched_clock.c b/arch/arm/kernel/sched_clock.c
index bd6f56b..040168e 100644
--- a/arch/arm/kernel/sched_clock.c
+++ b/arch/arm/kernel/sched_clock.c
@@ -20,6 +20,7 @@ struct clock_data {
 	u64 epoch_ns;
 	u32 epoch_cyc;
 	u32 epoch_cyc_copy;
+	unsigned long rate;
 	u32 mult;
 	u32 shift;
 	bool suspended;
@@ -113,11 +114,14 @@ void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate)
 	u64 res, wrap;
 	char r_unit;
 
+	if (cd.rate > rate)
+		return;
+
 	BUG_ON(bits > 32);
 	WARN_ON(!irqs_disabled());
-	WARN_ON(read_sched_clock != jiffy_sched_clock_read);
 	read_sched_clock = read;
 	sched_clock_mask = (1 << bits) - 1;
+	cd.rate = rate;
 
 	/* calculate the mult/shift to convert counter ticks to ns. */
 	clocks_calc_mult_shift(&cd.mult, &cd.shift, rate, NSEC_PER_SEC, 0);
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 2/3] ARM: make sched_clock just call a function pointer
  2013-04-01 20:58 [PATCH v2 0/3] ARM sched_clock selection enhancements Rob Herring
  2013-04-01 20:58 ` [PATCH v2 1/3] ARM: sched_clock: allow changing to higher frequency counter Rob Herring
@ 2013-04-01 20:58 ` Rob Herring
  2013-04-01 20:58 ` [PATCH v2 3/3] ARM: arch_timer: use full 64-bit counter for sched_clock Rob Herring
  2 siblings, 0 replies; 5+ messages in thread
From: Rob Herring @ 2013-04-01 20:58 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rob Herring <rob.herring@calxeda.com>

This converts sched_clock to simply a call to a function pointer in order
to allow overriding it. This will allow for use with 64-bit counters where
overflow handling is not needed.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 arch/arm/include/asm/sched_clock.h |    2 ++
 arch/arm/kernel/sched_clock.c      |    9 ++++++++-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/sched_clock.h b/arch/arm/include/asm/sched_clock.h
index e3f7572..3d520dd 100644
--- a/arch/arm/include/asm/sched_clock.h
+++ b/arch/arm/include/asm/sched_clock.h
@@ -11,4 +11,6 @@
 extern void sched_clock_postinit(void);
 extern void setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate);
 
+extern unsigned long long (*sched_clock_func)(void);
+
 #endif
diff --git a/arch/arm/kernel/sched_clock.c b/arch/arm/kernel/sched_clock.c
index 040168e..8805848 100644
--- a/arch/arm/kernel/sched_clock.c
+++ b/arch/arm/kernel/sched_clock.c
@@ -165,12 +165,19 @@ void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate)
 	pr_debug("Registered %pF as sched_clock source\n", read);
 }
 
-unsigned long long notrace sched_clock(void)
+static unsigned long long notrace sched_clock_32(void)
 {
 	u32 cyc = read_sched_clock();
 	return cyc_to_sched_clock(cyc, sched_clock_mask);
 }
 
+unsigned long long __read_mostly (*sched_clock_func)(void) = sched_clock_32;
+
+unsigned long long notrace sched_clock(void)
+{
+	return sched_clock_func();
+}
+
 void __init sched_clock_postinit(void)
 {
 	/*
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 3/3] ARM: arch_timer: use full 64-bit counter for sched_clock
  2013-04-01 20:58 [PATCH v2 0/3] ARM sched_clock selection enhancements Rob Herring
  2013-04-01 20:58 ` [PATCH v2 1/3] ARM: sched_clock: allow changing to higher frequency counter Rob Herring
  2013-04-01 20:58 ` [PATCH v2 2/3] ARM: make sched_clock just call a function pointer Rob Herring
@ 2013-04-01 20:58 ` Rob Herring
  2013-04-19 16:27   ` Russell King - ARM Linux
  2 siblings, 1 reply; 5+ messages in thread
From: Rob Herring @ 2013-04-01 20:58 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rob Herring <rob.herring@calxeda.com>

Only 32-bits of the arch timer were being used and wrapping was needlessly
being done in s/w. By using the full counter (56-64 bits), we don't need
to deal with wrapping and can simplify the implementation when using
arch timer.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 arch/arm/kernel/arch_timer.c |   15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/arch/arm/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c
index d957a51..a7536d4 100644
--- a/arch/arm/kernel/arch_timer.c
+++ b/arch/arm/kernel/arch_timer.c
@@ -22,9 +22,11 @@ static unsigned long arch_timer_read_counter_long(void)
 	return arch_timer_read_counter();
 }
 
-static u32 arch_timer_read_counter_u32(void)
+static u32 sched_clock_mult __read_mostly;
+
+static unsigned long long notrace arch_timer_sched_clock(void)
 {
-	return arch_timer_read_counter();
+	return arch_timer_read_counter() * sched_clock_mult;
 }
 
 static struct delay_timer arch_delay_timer;
@@ -52,10 +54,13 @@ int __init arch_timer_of_register(void)
 
 int __init arch_timer_sched_clock_init(void)
 {
-	if (arch_timer_get_rate() == 0)
+        u32 arch_timer_rate = arch_timer_get_rate();
+
+	if (arch_timer_rate == 0)
 		return -ENXIO;
 
-	setup_sched_clock(arch_timer_read_counter_u32,
-			  32, arch_timer_get_rate());
+	/* Cache the sched_clock multiplier to save a divide in the hot path. */
+	sched_clock_mult = NSEC_PER_SEC / arch_timer_rate;
+	sched_clock_func = arch_timer_sched_clock;
 	return 0;
 }
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 3/3] ARM: arch_timer: use full 64-bit counter for sched_clock
  2013-04-01 20:58 ` [PATCH v2 3/3] ARM: arch_timer: use full 64-bit counter for sched_clock Rob Herring
@ 2013-04-19 16:27   ` Russell King - ARM Linux
  0 siblings, 0 replies; 5+ messages in thread
From: Russell King - ARM Linux @ 2013-04-19 16:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Apr 01, 2013 at 03:58:34PM -0500, Rob Herring wrote:
> From: Rob Herring <rob.herring@calxeda.com>
> 
> Only 32-bits of the arch timer were being used and wrapping was needlessly
> being done in s/w. By using the full counter (56-64 bits), we don't need
> to deal with wrapping and can simplify the implementation when using
> arch timer.

Remember that you _must_ provide the full 64-bit nsec value to the
scheduler.  A 56-bit value will not do, it has to be the full 64-bits
of nsecs.  So:

> +static unsigned long long notrace arch_timer_sched_clock(void)
>  {
> -	return arch_timer_read_counter();
> +	return arch_timer_read_counter() * sched_clock_mult;
...
> +	/* Cache the sched_clock multiplier to save a divide in the hot path. */
> +	sched_clock_mult = NSEC_PER_SEC / arch_timer_rate;

If the counter is 56-bit and the multiplier is not larger than 255,
then you have a potential problem here.  That basically translates
into a clock rate of no more than 3.9MHz for the architected timer
if it is 56-bit.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2013-04-19 16:27 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-04-01 20:58 [PATCH v2 0/3] ARM sched_clock selection enhancements Rob Herring
2013-04-01 20:58 ` [PATCH v2 1/3] ARM: sched_clock: allow changing to higher frequency counter Rob Herring
2013-04-01 20:58 ` [PATCH v2 2/3] ARM: make sched_clock just call a function pointer Rob Herring
2013-04-01 20:58 ` [PATCH v2 3/3] ARM: arch_timer: use full 64-bit counter for sched_clock Rob Herring
2013-04-19 16:27   ` Russell King - ARM Linux

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).