aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clocksource/arc_timer.c
diff options
context:
space:
mode:
authorAlexey Brodkin <alexey.brodkin@synopsys.com>2018-11-19 06:29:17 -0500
committerDaniel Lezcano <daniel.lezcano@linaro.org>2018-12-18 16:22:23 -0500
commitbf287607c80f24387fedb431a346dc67f25be12c (patch)
treec2c0450742868addbf70642c01504c12e559048c /drivers/clocksource/arc_timer.c
parent2bbaf54216448486def1153486778a975a73041d (diff)
clocksource/drivers/arc_timer: Utilize generic sched_clock
It turned out we used to use default implementation of sched_clock() from kernel/sched/clock.c which was as precise as 1/HZ, i.e. by default we had 10 msec granularity of time measurement. Now given ARC built-in timers are clocked with the same frequency as CPU cores we may get much higher precision of time tracking. Thus we switch to generic sched_clock which really reads ARC hardware counters. This is especially helpful for measuring short events. That's what we used to have: ------------------------------>8------------------------ $ perf stat /bin/sh -c /root/lmbench-master/bin/arc/hello > /dev/null Performance counter stats for '/bin/sh -c /root/lmbench-master/bin/arc/hello': 10.000000 task-clock (msec) # 2.832 CPUs utilized 1 context-switches # 0.100 K/sec 1 cpu-migrations # 0.100 K/sec 63 page-faults # 0.006 M/sec 3049480 cycles # 0.305 GHz 1091259 instructions # 0.36 insn per cycle 256828 branches # 25.683 M/sec 27026 branch-misses # 10.52% of all branches 0.003530687 seconds time elapsed 0.000000000 seconds user 0.010000000 seconds sys ------------------------------>8------------------------ And now we'll see: ------------------------------>8------------------------ $ perf stat /bin/sh -c /root/lmbench-master/bin/arc/hello > /dev/null Performance counter stats for '/bin/sh -c /root/lmbench-master/bin/arc/hello': 3.004322 task-clock (msec) # 0.865 CPUs utilized 1 context-switches # 0.333 K/sec 1 cpu-migrations # 0.333 K/sec 63 page-faults # 0.021 M/sec 2986734 cycles # 0.994 GHz 1087466 instructions # 0.36 insn per cycle 255209 branches # 84.947 M/sec 26002 branch-misses # 10.19% of all branches 0.003474829 seconds time elapsed 0.003519000 seconds user 0.000000000 seconds sys ------------------------------>8------------------------ Note how much more meaningful is the second output - time spent for execution pretty much matches number of cycles spent (we're runnign @ 1GHz here). Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com> Cc: Daniel Lezcano <daniel.lezcano@linaro.org> Cc: Vineet Gupta <vgupta@synopsys.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: stable@vger.kernel.org Acked-by: Vineet Gupta <vgupta@synopsys.com> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Diffstat (limited to 'drivers/clocksource/arc_timer.c')
-rw-r--r--drivers/clocksource/arc_timer.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/drivers/clocksource/arc_timer.c b/drivers/clocksource/arc_timer.c
index 20da9b1d7f7d..b28970ca4a7a 100644
--- a/drivers/clocksource/arc_timer.c
+++ b/drivers/clocksource/arc_timer.c
@@ -23,6 +23,7 @@
23#include <linux/cpu.h> 23#include <linux/cpu.h>
24#include <linux/of.h> 24#include <linux/of.h>
25#include <linux/of_irq.h> 25#include <linux/of_irq.h>
26#include <linux/sched_clock.h>
26 27
27#include <soc/arc/timers.h> 28#include <soc/arc/timers.h>
28#include <soc/arc/mcip.h> 29#include <soc/arc/mcip.h>
@@ -88,6 +89,11 @@ static u64 arc_read_gfrc(struct clocksource *cs)
88 return (((u64)h) << 32) | l; 89 return (((u64)h) << 32) | l;
89} 90}
90 91
92static notrace u64 arc_gfrc_clock_read(void)
93{
94 return arc_read_gfrc(NULL);
95}
96
91static struct clocksource arc_counter_gfrc = { 97static struct clocksource arc_counter_gfrc = {
92 .name = "ARConnect GFRC", 98 .name = "ARConnect GFRC",
93 .rating = 400, 99 .rating = 400,
@@ -111,6 +117,8 @@ static int __init arc_cs_setup_gfrc(struct device_node *node)
111 if (ret) 117 if (ret)
112 return ret; 118 return ret;
113 119
120 sched_clock_register(arc_gfrc_clock_read, 64, arc_timer_freq);
121
114 return clocksource_register_hz(&arc_counter_gfrc, arc_timer_freq); 122 return clocksource_register_hz(&arc_counter_gfrc, arc_timer_freq);
115} 123}
116TIMER_OF_DECLARE(arc_gfrc, "snps,archs-timer-gfrc", arc_cs_setup_gfrc); 124TIMER_OF_DECLARE(arc_gfrc, "snps,archs-timer-gfrc", arc_cs_setup_gfrc);
@@ -139,6 +147,11 @@ static u64 arc_read_rtc(struct clocksource *cs)
139 return (((u64)h) << 32) | l; 147 return (((u64)h) << 32) | l;
140} 148}
141 149
150static notrace u64 arc_rtc_clock_read(void)
151{
152 return arc_read_rtc(NULL);
153}
154
142static struct clocksource arc_counter_rtc = { 155static struct clocksource arc_counter_rtc = {
143 .name = "ARCv2 RTC", 156 .name = "ARCv2 RTC",
144 .rating = 350, 157 .rating = 350,
@@ -170,6 +183,8 @@ static int __init arc_cs_setup_rtc(struct device_node *node)
170 183
171 write_aux_reg(AUX_RTC_CTRL, 1); 184 write_aux_reg(AUX_RTC_CTRL, 1);
172 185
186 sched_clock_register(arc_rtc_clock_read, 64, arc_timer_freq);
187
173 return clocksource_register_hz(&arc_counter_rtc, arc_timer_freq); 188 return clocksource_register_hz(&arc_counter_rtc, arc_timer_freq);
174} 189}
175TIMER_OF_DECLARE(arc_rtc, "snps,archs-timer-rtc", arc_cs_setup_rtc); 190TIMER_OF_DECLARE(arc_rtc, "snps,archs-timer-rtc", arc_cs_setup_rtc);
@@ -185,6 +200,11 @@ static u64 arc_read_timer1(struct clocksource *cs)
185 return (u64) read_aux_reg(ARC_REG_TIMER1_CNT); 200 return (u64) read_aux_reg(ARC_REG_TIMER1_CNT);
186} 201}
187 202
203static notrace u64 arc_timer1_clock_read(void)
204{
205 return arc_read_timer1(NULL);
206}
207
188static struct clocksource arc_counter_timer1 = { 208static struct clocksource arc_counter_timer1 = {
189 .name = "ARC Timer1", 209 .name = "ARC Timer1",
190 .rating = 300, 210 .rating = 300,
@@ -209,6 +229,8 @@ static int __init arc_cs_setup_timer1(struct device_node *node)
209 write_aux_reg(ARC_REG_TIMER1_CNT, 0); 229 write_aux_reg(ARC_REG_TIMER1_CNT, 0);
210 write_aux_reg(ARC_REG_TIMER1_CTRL, TIMER_CTRL_NH); 230 write_aux_reg(ARC_REG_TIMER1_CTRL, TIMER_CTRL_NH);
211 231
232 sched_clock_register(arc_timer1_clock_read, 32, arc_timer_freq);
233
212 return clocksource_register_hz(&arc_counter_timer1, arc_timer_freq); 234 return clocksource_register_hz(&arc_counter_timer1, arc_timer_freq);
213} 235}
214 236