Skip to content

Commit

Permalink
timekeeping: Move NTP adjusted clock multiplier to struct timekeeper
Browse files Browse the repository at this point in the history
The clocksource structure has two multipliers, the unmodified multiplier
clock->mult_orig and the NTP corrected multiplier clock->mult. The NTP
multiplier is misplaced in the struct clocksource, this is private
information of the timekeeping code. Add the mult field to the struct
timekeeper to contain the NTP corrected value, keep the unmodifed
multiplier in clock->mult and remove clock->mult_orig.

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: <20090814134810.149047645@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 23ce721 commit 0a54419
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 37 deletions.
7 changes: 2 additions & 5 deletions arch/arm/plat-omap/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,11 +253,8 @@ static struct clocksource clocksource_32k = {
*/
unsigned long long sched_clock(void)
{
unsigned long long ret;

ret = (unsigned long long)clocksource_32k.read(&clocksource_32k);
ret = (ret * clocksource_32k.mult_orig) >> clocksource_32k.shift;
return ret;
return clocksource_cyc2ns(clocksource_32k.read(&clocksource_32k),
clocksource_32k.mult, clocksource_32k.shift);
}

static int __init omap_init_clocksource_32k(void)
Expand Down
4 changes: 1 addition & 3 deletions include/linux/clocksource.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,7 @@ extern u64 timecounter_cyc2time(struct timecounter *tc,
* @disable: optional function to disable the clocksource
* @mask: bitmask for two's complement
* subtraction of non 64 bit counters
* @mult: cycle to nanosecond multiplier (adjusted by NTP)
* @mult_orig: cycle to nanosecond multiplier (unadjusted by NTP)
* @mult: cycle to nanosecond multiplier
* @shift: cycle to nanosecond divisor (power of two)
* @flags: flags describing special properties
* @vread: vsyscall based read
Expand All @@ -168,7 +167,6 @@ struct clocksource {
void (*disable)(struct clocksource *cs);
cycle_t mask;
u32 mult;
u32 mult_orig;
u32 shift;
unsigned long flags;
cycle_t (*vread)(void);
Expand Down
53 changes: 24 additions & 29 deletions kernel/time/timekeeping.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ struct timekeeper {
/* Shift conversion between clock shifted nano seconds and
* ntp shifted nano seconds. */
int ntp_error_shift;
/* NTP adjusted clock multiplier */
u32 mult;
};

struct timekeeper timekeeper;
Expand All @@ -66,8 +68,8 @@ static void timekeeper_setup_internals(struct clocksource *clock)
/* Do the ns -> cycle conversion first, using original mult */
tmp = NTP_INTERVAL_LENGTH;
tmp <<= clock->shift;
tmp += clock->mult_orig/2;
do_div(tmp, clock->mult_orig);
tmp += clock->mult/2;
do_div(tmp, clock->mult);
if (tmp == 0)
tmp = 1;

Expand All @@ -77,13 +79,20 @@ static void timekeeper_setup_internals(struct clocksource *clock)
/* Go back from cycles -> shifted ns */
timekeeper.xtime_interval = (u64) interval * clock->mult;
timekeeper.raw_interval =
((u64) interval * clock->mult_orig) >> clock->shift;
((u64) interval * clock->mult) >> clock->shift;

timekeeper.xtime_nsec = 0;
timekeeper.shift = clock->shift;

timekeeper.ntp_error = 0;
timekeeper.ntp_error_shift = NTP_SCALE_SHIFT - clock->shift;

/*
* The timekeeper keeps its own mult values for the currently
* active clocksource. These value will be adjusted via NTP
* to counteract clock drifting.
*/
timekeeper.mult = clock->mult;
}

/*
Expand Down Expand Up @@ -154,14 +163,15 @@ static void timekeeping_forward_now(void)
cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;
clock->cycle_last = cycle_now;

nsec = clocksource_cyc2ns(cycle_delta, clock->mult, clock->shift);
nsec = clocksource_cyc2ns(cycle_delta, timekeeper.mult,
timekeeper.shift);

/* If arch requires, add in gettimeoffset() */
nsec += arch_gettimeoffset();

timespec_add_ns(&xtime, nsec);

nsec = clocksource_cyc2ns(cycle_delta, clock->mult_orig, clock->shift);
nsec = clocksource_cyc2ns(cycle_delta, clock->mult, clock->shift);
timespec_add_ns(&raw_time, nsec);
}

Expand Down Expand Up @@ -193,8 +203,8 @@ void getnstimeofday(struct timespec *ts)
cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;

/* convert to nanoseconds: */
nsecs = clocksource_cyc2ns(cycle_delta, clock->mult,
clock->shift);
nsecs = clocksource_cyc2ns(cycle_delta, timekeeper.mult,
timekeeper.shift);

/* If arch requires, add in gettimeoffset() */
nsecs += arch_gettimeoffset();
Expand Down Expand Up @@ -228,8 +238,8 @@ ktime_t ktime_get(void)
cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;

/* convert to nanoseconds: */
nsecs += clocksource_cyc2ns(cycle_delta, clock->mult,
clock->shift);
nsecs += clocksource_cyc2ns(cycle_delta, timekeeper.mult,
timekeeper.shift);

} while (read_seqretry(&xtime_lock, seq));
/*
Expand Down Expand Up @@ -271,8 +281,8 @@ void ktime_get_ts(struct timespec *ts)
cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;

/* convert to nanoseconds: */
nsecs = clocksource_cyc2ns(cycle_delta, clock->mult,
clock->shift);
nsecs = clocksource_cyc2ns(cycle_delta, timekeeper.mult,
timekeeper.shift);

} while (read_seqretry(&xtime_lock, seq));

Expand Down Expand Up @@ -356,22 +366,10 @@ static void change_clocksource(void)

if (new->enable && !new->enable(new))
return;
/*
* The frequency may have changed while the clocksource
* was disabled. If so the code in ->enable() must update
* the mult value to reflect the new frequency. Make sure
* mult_orig follows this change.
*/
new->mult_orig = new->mult;

old = timekeeper.clock;
timekeeper_setup_internals(new);

/*
* Save mult_orig in mult so that the value can be restored
* regardless if ->enable() updates the value of mult or not.
*/
old->mult = old->mult_orig;
if (old->disable)
old->disable(old);

Expand Down Expand Up @@ -461,7 +459,7 @@ void getrawmonotonic(struct timespec *ts)
cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;

/* convert to nanoseconds: */
nsecs = clocksource_cyc2ns(cycle_delta, clock->mult_orig,
nsecs = clocksource_cyc2ns(cycle_delta, clock->mult,
clock->shift);

*ts = raw_time;
Expand Down Expand Up @@ -521,9 +519,6 @@ void __init timekeeping_init(void)
clock = clocksource_default_clock();
if (clock->enable)
clock->enable(clock);
/* set mult_orig on enable */
clock->mult_orig = clock->mult;

timekeeper_setup_internals(clock);

xtime.tv_sec = sec;
Expand Down Expand Up @@ -697,7 +692,7 @@ static void timekeeping_adjust(s64 offset)
} else
return;

timekeeper.clock->mult += adj;
timekeeper.mult += adj;
timekeeper.xtime_interval += interval;
timekeeper.xtime_nsec -= offset;
timekeeper.ntp_error -= (interval - offset) <<
Expand Down Expand Up @@ -789,7 +784,7 @@ void update_wall_time(void)
timekeeper.ntp_error += timekeeper.xtime_nsec <<
timekeeper.ntp_error_shift;

nsecs = clocksource_cyc2ns(offset, clock->mult, clock->shift);
nsecs = clocksource_cyc2ns(offset, timekeeper.mult, timekeeper.shift);
update_xtime_cache(nsecs);

/* check to see if there is a new clocksource to use */
Expand Down

0 comments on commit 0a54419

Please sign in to comment.