Skip to content

Commit

Permalink
timekeeping: Introduce struct timekeeper
Browse files Browse the repository at this point in the history
Add struct timekeeper to keep the internal values timekeeping.c needs
in regard to the currently selected clock source. This moves the
timekeeping intervals, xtime_nsec and the ntp error value from struct
clocksource to struct timekeeper. The raw_time is removed from the
clocksource as well. It gets treated like xtime as a global variable.
Eventually xtime raw_time should be moved to struct timekeeper.

[ tglx: minor cleanup ]

Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Ingo Molnar <mingo@elte.hu>
Acked-by: John Stultz <johnstul@us.ibm.com>
Cc: Daniel Walker <dwalker@fifo99.com>
LKML-Reference: <20090814134809.613209842@de.ibm.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
  • Loading branch information
Martin Schwidefsky authored and Thomas Gleixner committed Aug 15, 2009
1 parent c55c87c commit 155ec60
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 132 deletions.
1 change: 0 additions & 1 deletion arch/s390/kernel/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,6 @@ void __init time_init(void)
now = get_clock();
tod_to_timeval(now - TOD_UNIX_EPOCH, &xtime);
clocksource_tod.cycle_last = now;
clocksource_tod.raw_time = xtime;
tod_to_timeval(sched_clock_base_cc - TOD_UNIX_EPOCH, &ts);
set_normalized_timespec(&wall_to_monotonic, -ts.tv_sec, -ts.tv_nsec);
write_sequnlock_irqrestore(&xtime_lock, flags);
Expand Down
54 changes: 4 additions & 50 deletions include/linux/clocksource.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,6 @@ extern u64 timecounter_cyc2time(struct timecounter *tc,
* @flags: flags describing special properties
* @vread: vsyscall based read
* @resume: resume function for the clocksource, if necessary
* @cycle_interval: Used internally by timekeeping core, please ignore.
* @xtime_interval: Used internally by timekeeping core, please ignore.
*/
struct clocksource {
/*
Expand All @@ -182,19 +180,12 @@ struct clocksource {
#define CLKSRC_FSYS_MMIO_SET(mmio, addr) do { } while (0)
#endif

/* timekeeping specific data, ignore */
cycle_t cycle_interval;
u64 xtime_interval;
u32 raw_interval;
/*
* Second part is written at each timer interrupt
* Keep it in a different cache line to dirty no
* more than one cache line.
*/
cycle_t cycle_last ____cacheline_aligned_in_smp;
u64 xtime_nsec;
s64 error;
struct timespec raw_time;

#ifdef CONFIG_CLOCKSOURCE_WATCHDOG
/* Watchdog related data, used by the framework */
Expand All @@ -203,8 +194,6 @@ struct clocksource {
#endif
};

extern struct clocksource *clock; /* current clocksource */

/*
* Clock source flags bits::
*/
Expand Down Expand Up @@ -270,50 +259,15 @@ static inline u32 clocksource_hz2mult(u32 hz, u32 shift_constant)
}

/**
* cyc2ns - converts clocksource cycles to nanoseconds
* @cs: Pointer to clocksource
* @cycles: Cycles
* clocksource_cyc2ns - converts clocksource cycles to nanoseconds
*
* Uses the clocksource and ntp ajdustment to convert cycle_ts to nanoseconds.
* Converts cycles to nanoseconds, using the given mult and shift.
*
* XXX - This could use some mult_lxl_ll() asm optimization
*/
static inline s64 cyc2ns(struct clocksource *cs, cycle_t cycles)
static inline s64 clocksource_cyc2ns(cycle_t cycles, u32 mult, u32 shift)
{
u64 ret = (u64)cycles;
ret = (ret * cs->mult) >> cs->shift;
return ret;
}

/**
* clocksource_calculate_interval - Calculates a clocksource interval struct
*
* @c: Pointer to clocksource.
* @length_nsec: Desired interval length in nanoseconds.
*
* Calculates a fixed cycle/nsec interval for a given clocksource/adjustment
* pair and interval request.
*
* Unless you're the timekeeping code, you should not be using this!
*/
static inline void clocksource_calculate_interval(struct clocksource *c,
unsigned long length_nsec)
{
u64 tmp;

/* Do the ns -> cycle conversion first, using original mult */
tmp = length_nsec;
tmp <<= c->shift;
tmp += c->mult_orig/2;
do_div(tmp, c->mult_orig);

c->cycle_interval = (cycle_t)tmp;
if (c->cycle_interval == 0)
c->cycle_interval = 1;

/* Go back from cycles -> shifted ns, this time use ntp adjused mult */
c->xtime_interval = (u64)c->cycle_interval * c->mult;
c->raw_interval = ((u64)c->cycle_interval * c->mult_orig) >> c->shift;
return ((u64) cycles * mult) >> shift;
}


Expand Down
6 changes: 4 additions & 2 deletions kernel/time/clocksource.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,8 @@ static void clocksource_watchdog(unsigned long data)
goto out;

wdnow = watchdog->read(watchdog);
wd_nsec = cyc2ns(watchdog, (wdnow - watchdog_last) & watchdog->mask);
wd_nsec = clocksource_cyc2ns((wdnow - watchdog_last) & watchdog->mask,
watchdog->mult, watchdog->shift);
watchdog_last = wdnow;

list_for_each_entry(cs, &watchdog_list, wd_list) {
Expand All @@ -196,7 +197,8 @@ static void clocksource_watchdog(unsigned long data)
}

/* Check the deviation from the watchdog clocksource. */
cs_nsec = cyc2ns(cs, (csnow - cs->wd_last) & cs->mask);
cs_nsec = clocksource_cyc2ns((csnow - cs->wd_last) &
cs->mask, cs->mult, cs->shift);
cs->wd_last = csnow;
if (abs(cs_nsec - wd_nsec) > WATCHDOG_THRESHOLD) {
clocksource_unstable(cs, cs_nsec - wd_nsec);
Expand Down
Loading

0 comments on commit 155ec60

Please sign in to comment.