65 #include <linux/export.h>
68 #include <linux/sched.h>
84 #ifdef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK
87 struct sched_clock_data {
95 static inline struct sched_clock_data *this_scd(
void)
100 static inline struct sched_clock_data *cpu_sdc(
int cpu)
102 return &
per_cpu(sched_clock_data, cpu);
111 struct sched_clock_data *scd = cpu_sdc(cpu);
114 scd->tick_gtod = ktime_now;
115 scd->clock = ktime_now;
118 sched_clock_running = 1;
127 return (
s64)(x -
y) < 0 ? x : y;
132 return (
s64)(x -
y) > 0 ? x : y;
141 static u64 sched_clock_local(
struct sched_clock_data *scd)
143 u64 now,
clock, old_clock, min_clock, max_clock;
148 delta = now - scd->tick_raw;
152 old_clock = scd->clock;
160 clock = scd->tick_gtod +
delta;
161 min_clock = wrap_max(scd->tick_gtod, old_clock);
162 max_clock = wrap_max(old_clock, scd->tick_gtod +
TICK_NSEC);
164 clock = wrap_max(clock, min_clock);
165 clock = wrap_min(clock, max_clock);
167 if (
cmpxchg64(&scd->clock, old_clock, clock) != old_clock)
173 static u64 sched_clock_remote(
struct sched_clock_data *scd)
175 struct sched_clock_data *my_scd = this_scd();
176 u64 this_clock, remote_clock;
179 sched_clock_local(my_scd);
181 this_clock = my_scd->clock;
182 remote_clock = scd->clock;
190 if (
likely((
s64)(remote_clock - this_clock) < 0)) {
192 old_val = remote_clock;
198 ptr = &my_scd->clock;
199 old_val = this_clock;
203 if (
cmpxchg64(ptr, old_val, val) != old_val)
216 struct sched_clock_data *scd;
221 if (sched_clock_stable)
230 clock = sched_clock_remote(scd);
232 clock = sched_clock_local(scd);
237 void sched_clock_tick(
void)
239 struct sched_clock_data *scd;
242 if (sched_clock_stable)
255 scd->tick_gtod = now_gtod;
256 sched_clock_local(scd);
262 void sched_clock_idle_sleep_event(
void)
271 void sched_clock_idle_wakeup_event(
u64 delta_ns)
326 sched_clock_running = 1;