diff options
Diffstat (limited to 'kernel/time')
| -rw-r--r-- | kernel/time/tick-sched.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index b0741801c4c7..c1f3aca1a01d 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -46,6 +46,38 @@ static DEFINE_PER_CPU(struct tick_sched, tick_cpu_sched); */ static ktime_t last_jiffies_update; +/* + * Conversion from ktime to sched_clock is error prone. Use this + * as a safetly margin when calculating the sched_clock value at + * a particular jiffy as last_jiffies_update uses ktime. + */ +#define SCHED_CLOCK_MARGIN 100000 + +static u64 ns_since_jiffy(void) +{ + ktime_t delta; + + delta = ktime_sub(ktime_get(), last_jiffies_update); + + return ktime_to_ns(delta); +} + +u64 jiffy_to_sched_clock(u64 *now, u64 *jiffy_sched_clock) +{ + u64 cur_jiffies; + unsigned long seq; + + do { + seq = read_seqbegin(&jiffies_lock); + *now = sched_clock(); + *jiffy_sched_clock = *now - + (ns_since_jiffy() + SCHED_CLOCK_MARGIN); + cur_jiffies = get_jiffies_64(); + } while (read_seqretry(&jiffies_lock, seq)); + + return cur_jiffies; +} + struct tick_sched *tick_get_tick_sched(int cpu) { return &per_cpu(tick_cpu_sched, cpu); |
