* [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