diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-02-26 14:20:29 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-02-26 15:20:22 -0500 |
commit | b342501cd31e5546d0c9ca8ceff5ded1832f9e5b (patch) | |
tree | 3cd5778565a45a74e8ad0640093927a77d4d625e /kernel | |
parent | 694593e3374a67d95ece6a275a1f181644c2c4d8 (diff) |
sched: allow architectures to specify sched_clock_stable
Allow CONFIG_HAVE_UNSTABLE_SCHED_CLOCK architectures to still specify
that their sched_clock() implementation is reliable.
This will be used by x86 to switch on a faster sched_clock_cpu()
implementation on certain CPU types.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/sched_clock.c | 45 |
1 files changed, 20 insertions, 25 deletions
diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c index a0b0852414cc..a755d023805a 100644 --- a/kernel/sched_clock.c +++ b/kernel/sched_clock.c | |||
@@ -24,11 +24,11 @@ | |||
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> | ||
31 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/percpu.h> | ||
30 | #include <linux/ktime.h> | ||
31 | #include <linux/sched.h> | ||
32 | 32 | ||
33 | /* | 33 | /* |
34 | * Scheduler clock - returns current time in nanosec units. | 34 | * Scheduler clock - returns current time in nanosec units. |
@@ -43,6 +43,10 @@ unsigned long long __attribute__((weak)) sched_clock(void) | |||
43 | static __read_mostly int sched_clock_running; | 43 | static __read_mostly int sched_clock_running; |
44 | 44 | ||
45 | #ifdef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK | 45 | #ifdef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK |
46 | __read_mostly int sched_clock_stable; | ||
47 | #else | ||
48 | static const int sched_clock_stable = 1; | ||
49 | #endif | ||
46 | 50 | ||
47 | struct sched_clock_data { | 51 | struct sched_clock_data { |
48 | /* | 52 | /* |
@@ -87,7 +91,7 @@ void sched_clock_init(void) | |||
87 | } | 91 | } |
88 | 92 | ||
89 | /* | 93 | /* |
90 | * min,max except they take wrapping into account | 94 | * min, max except they take wrapping into account |
91 | */ | 95 | */ |
92 | 96 | ||
93 | static inline u64 wrap_min(u64 x, u64 y) | 97 | static inline u64 wrap_min(u64 x, u64 y) |
@@ -116,10 +120,13 @@ static u64 __update_sched_clock(struct sched_clock_data *scd, u64 now) | |||
116 | if (unlikely(delta < 0)) | 120 | if (unlikely(delta < 0)) |
117 | delta = 0; | 121 | delta = 0; |
118 | 122 | ||
123 | if (unlikely(!sched_clock_running)) | ||
124 | return 0ull; | ||
125 | |||
119 | /* | 126 | /* |
120 | * scd->clock = clamp(scd->tick_gtod + delta, | 127 | * scd->clock = clamp(scd->tick_gtod + delta, |
121 | * max(scd->tick_gtod, scd->clock), | 128 | * max(scd->tick_gtod, scd->clock), |
122 | * scd->tick_gtod + TICK_NSEC); | 129 | * scd->tick_gtod + TICK_NSEC); |
123 | */ | 130 | */ |
124 | 131 | ||
125 | clock = scd->tick_gtod + delta; | 132 | clock = scd->tick_gtod + delta; |
@@ -148,12 +155,13 @@ static void lock_double_clock(struct sched_clock_data *data1, | |||
148 | 155 | ||
149 | u64 sched_clock_cpu(int cpu) | 156 | u64 sched_clock_cpu(int cpu) |
150 | { | 157 | { |
151 | struct sched_clock_data *scd = cpu_sdc(cpu); | ||
152 | u64 now, clock, this_clock, remote_clock; | 158 | u64 now, clock, this_clock, remote_clock; |
159 | struct sched_clock_data *scd; | ||
153 | 160 | ||
154 | if (unlikely(!sched_clock_running)) | 161 | if (sched_clock_stable) |
155 | return 0ull; | 162 | return sched_clock(); |
156 | 163 | ||
164 | scd = cpu_sdc(cpu); | ||
157 | WARN_ON_ONCE(!irqs_disabled()); | 165 | WARN_ON_ONCE(!irqs_disabled()); |
158 | now = sched_clock(); | 166 | now = sched_clock(); |
159 | 167 | ||
@@ -193,6 +201,8 @@ u64 sched_clock_cpu(int cpu) | |||
193 | return clock; | 201 | return clock; |
194 | } | 202 | } |
195 | 203 | ||
204 | #ifdef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK | ||
205 | |||
196 | void sched_clock_tick(void) | 206 | void sched_clock_tick(void) |
197 | { | 207 | { |
198 | struct sched_clock_data *scd = this_scd(); | 208 | struct sched_clock_data *scd = this_scd(); |
@@ -235,22 +245,7 @@ void sched_clock_idle_wakeup_event(u64 delta_ns) | |||
235 | } | 245 | } |
236 | EXPORT_SYMBOL_GPL(sched_clock_idle_wakeup_event); | 246 | EXPORT_SYMBOL_GPL(sched_clock_idle_wakeup_event); |
237 | 247 | ||
238 | #else /* CONFIG_HAVE_UNSTABLE_SCHED_CLOCK */ | 248 | #endif /* CONFIG_HAVE_UNSTABLE_SCHED_CLOCK */ |
239 | |||
240 | void sched_clock_init(void) | ||
241 | { | ||
242 | sched_clock_running = 1; | ||
243 | } | ||
244 | |||
245 | u64 sched_clock_cpu(int cpu) | ||
246 | { | ||
247 | if (unlikely(!sched_clock_running)) | ||
248 | return 0; | ||
249 | |||
250 | return sched_clock(); | ||
251 | } | ||
252 | |||
253 | #endif | ||
254 | 249 | ||
255 | unsigned long long cpu_clock(int cpu) | 250 | unsigned long long cpu_clock(int cpu) |
256 | { | 251 | { |