aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched_clock.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sched_clock.c')
-rw-r--r--kernel/sched_clock.c38
1 files changed, 27 insertions, 11 deletions
diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c
index a0b0852414cc..819f17ac796e 100644
--- a/kernel/sched_clock.c
+++ b/kernel/sched_clock.c
@@ -24,11 +24,12 @@
24 * The clock: sched_clock_cpu() is monotonic per cpu, and should be somewhat 24 * The clock: sched_clock_cpu() is monotonic per cpu, and should be somewhat
25 * consistent between cpus (never more than 2 jiffies difference). 25 * consistent between cpus (never more than 2 jiffies difference).
26 */ 26 */
27#include <linux/sched.h>
28#include <linux/percpu.h>
29#include <linux/spinlock.h> 27#include <linux/spinlock.h>
30#include <linux/ktime.h> 28#include <linux/hardirq.h>
31#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/percpu.h>
31#include <linux/ktime.h>
32#include <linux/sched.h>
32 33
33/* 34/*
34 * Scheduler clock - returns current time in nanosec units. 35 * Scheduler clock - returns current time in nanosec units.
@@ -43,6 +44,7 @@ unsigned long long __attribute__((weak)) sched_clock(void)
43static __read_mostly int sched_clock_running; 44static __read_mostly int sched_clock_running;
44 45
45#ifdef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK 46#ifdef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK
47__read_mostly int sched_clock_stable;
46 48
47struct sched_clock_data { 49struct sched_clock_data {
48 /* 50 /*
@@ -87,7 +89,7 @@ void sched_clock_init(void)
87} 89}
88 90
89/* 91/*
90 * min,max except they take wrapping into account 92 * min, max except they take wrapping into account
91 */ 93 */
92 94
93static inline u64 wrap_min(u64 x, u64 y) 95static inline u64 wrap_min(u64 x, u64 y)
@@ -111,15 +113,13 @@ static u64 __update_sched_clock(struct sched_clock_data *scd, u64 now)
111 s64 delta = now - scd->tick_raw; 113 s64 delta = now - scd->tick_raw;
112 u64 clock, min_clock, max_clock; 114 u64 clock, min_clock, max_clock;
113 115
114 WARN_ON_ONCE(!irqs_disabled());
115
116 if (unlikely(delta < 0)) 116 if (unlikely(delta < 0))
117 delta = 0; 117 delta = 0;
118 118
119 /* 119 /*
120 * scd->clock = clamp(scd->tick_gtod + delta, 120 * scd->clock = clamp(scd->tick_gtod + delta,
121 * max(scd->tick_gtod, scd->clock), 121 * max(scd->tick_gtod, scd->clock),
122 * scd->tick_gtod + TICK_NSEC); 122 * scd->tick_gtod + TICK_NSEC);
123 */ 123 */
124 124
125 clock = scd->tick_gtod + delta; 125 clock = scd->tick_gtod + delta;
@@ -148,8 +148,20 @@ static void lock_double_clock(struct sched_clock_data *data1,
148 148
149u64 sched_clock_cpu(int cpu) 149u64 sched_clock_cpu(int cpu)
150{ 150{
151 struct sched_clock_data *scd = cpu_sdc(cpu);
152 u64 now, clock, this_clock, remote_clock; 151 u64 now, clock, this_clock, remote_clock;
152 struct sched_clock_data *scd;
153
154 if (sched_clock_stable)
155 return sched_clock();
156
157 scd = cpu_sdc(cpu);
158
159 /*
160 * Normally this is not called in NMI context - but if it is,
161 * trying to do any locking here is totally lethal.
162 */
163 if (unlikely(in_nmi()))
164 return scd->clock;
153 165
154 if (unlikely(!sched_clock_running)) 166 if (unlikely(!sched_clock_running))
155 return 0ull; 167 return 0ull;
@@ -195,14 +207,18 @@ u64 sched_clock_cpu(int cpu)
195 207
196void sched_clock_tick(void) 208void sched_clock_tick(void)
197{ 209{
198 struct sched_clock_data *scd = this_scd(); 210 struct sched_clock_data *scd;
199 u64 now, now_gtod; 211 u64 now, now_gtod;
200 212
213 if (sched_clock_stable)
214 return;
215
201 if (unlikely(!sched_clock_running)) 216 if (unlikely(!sched_clock_running))
202 return; 217 return;
203 218
204 WARN_ON_ONCE(!irqs_disabled()); 219 WARN_ON_ONCE(!irqs_disabled());
205 220
221 scd = this_scd();
206 now_gtod = ktime_to_ns(ktime_get()); 222 now_gtod = ktime_to_ns(ktime_get());
207 now = sched_clock(); 223 now = sched_clock();
208 224
@@ -250,7 +266,7 @@ u64 sched_clock_cpu(int cpu)
250 return sched_clock(); 266 return sched_clock();
251} 267}
252 268
253#endif 269#endif /* CONFIG_HAVE_UNSTABLE_SCHED_CLOCK */
254 270
255unsigned long long cpu_clock(int cpu) 271unsigned long long cpu_clock(int cpu)
256{ 272{