Merge branch 'timers-timekeeping-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'timers-timekeeping-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
um: Fix read_persistent_clock fallout
kgdb: Do not access xtime directly
powerpc: Clean up obsolete code relating to decrementer and timebase
powerpc: Rework VDSO gettimeofday to prevent time going backwards
clocksource: Add __clocksource_updatefreq_hz/khz methods
x86: Convert common clocksources to use clocksource_register_hz/khz
timekeeping: Make xtime and wall_to_monotonic static
hrtimer: Cleanup direct access to wall_to_monotonic
um: Convert to use read_persistent_clock
timkeeping: Fix update_vsyscall to provide wall_to_monotonic offset
powerpc: Cleanup xtime usage
powerpc: Simplify update_vsyscall
time: Kill off CONFIG_GENERIC_TIME
time: Implement timespec_add
x86: Fix vtime/file timestamp inconsistencies
Trivial conflicts in Documentation/feature-removal-schedule.txt
Much less trivial conflicts in arch/powerpc/kernel/time.c resolved as
per Thomas' earlier merge commit 47916be4e2
("Merge branch
'powerpc.cherry-picks' into timers/clocksource")
This commit is contained in:
@@ -6,7 +6,7 @@ config TICK_ONESHOT
|
||||
|
||||
config NO_HZ
|
||||
bool "Tickless System (Dynamic Ticks)"
|
||||
depends on GENERIC_TIME && GENERIC_CLOCKEVENTS
|
||||
depends on !ARCH_USES_GETTIMEOFFSET && GENERIC_CLOCKEVENTS
|
||||
select TICK_ONESHOT
|
||||
help
|
||||
This option enables a tickless system: timer interrupts will
|
||||
@@ -15,7 +15,7 @@ config NO_HZ
|
||||
|
||||
config HIGH_RES_TIMERS
|
||||
bool "High Resolution Timer Support"
|
||||
depends on GENERIC_TIME && GENERIC_CLOCKEVENTS
|
||||
depends on !ARCH_USES_GETTIMEOFFSET && GENERIC_CLOCKEVENTS
|
||||
select TICK_ONESHOT
|
||||
help
|
||||
This option enables high resolution timer support. If your
|
||||
|
@@ -531,7 +531,7 @@ static u64 clocksource_max_deferment(struct clocksource *cs)
|
||||
return max_nsecs - (max_nsecs >> 5);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_GENERIC_TIME
|
||||
#ifndef CONFIG_ARCH_USES_GETTIMEOFFSET
|
||||
|
||||
/**
|
||||
* clocksource_select - Select the best clocksource available
|
||||
@@ -577,7 +577,7 @@ static void clocksource_select(void)
|
||||
}
|
||||
}
|
||||
|
||||
#else /* CONFIG_GENERIC_TIME */
|
||||
#else /* !CONFIG_ARCH_USES_GETTIMEOFFSET */
|
||||
|
||||
static inline void clocksource_select(void) { }
|
||||
|
||||
@@ -638,6 +638,32 @@ static void clocksource_enqueue(struct clocksource *cs)
|
||||
*/
|
||||
#define MAX_UPDATE_LENGTH 5 /* Seconds */
|
||||
|
||||
/**
|
||||
* __clocksource_updatefreq_scale - Used update clocksource with new freq
|
||||
* @t: clocksource to be registered
|
||||
* @scale: Scale factor multiplied against freq to get clocksource hz
|
||||
* @freq: clocksource frequency (cycles per second) divided by scale
|
||||
*
|
||||
* This should only be called from the clocksource->enable() method.
|
||||
*
|
||||
* This *SHOULD NOT* be called directly! Please use the
|
||||
* clocksource_updatefreq_hz() or clocksource_updatefreq_khz helper functions.
|
||||
*/
|
||||
void __clocksource_updatefreq_scale(struct clocksource *cs, u32 scale, u32 freq)
|
||||
{
|
||||
/*
|
||||
* Ideally we want to use some of the limits used in
|
||||
* clocksource_max_deferment, to provide a more informed
|
||||
* MAX_UPDATE_LENGTH. But for now this just gets the
|
||||
* register interface working properly.
|
||||
*/
|
||||
clocks_calc_mult_shift(&cs->mult, &cs->shift, freq,
|
||||
NSEC_PER_SEC/scale,
|
||||
MAX_UPDATE_LENGTH*scale);
|
||||
cs->max_idle_ns = clocksource_max_deferment(cs);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__clocksource_updatefreq_scale);
|
||||
|
||||
/**
|
||||
* __clocksource_register_scale - Used to install new clocksources
|
||||
* @t: clocksource to be registered
|
||||
@@ -652,17 +678,10 @@ static void clocksource_enqueue(struct clocksource *cs)
|
||||
int __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq)
|
||||
{
|
||||
|
||||
/*
|
||||
* Ideally we want to use some of the limits used in
|
||||
* clocksource_max_deferment, to provide a more informed
|
||||
* MAX_UPDATE_LENGTH. But for now this just gets the
|
||||
* register interface working properly.
|
||||
*/
|
||||
clocks_calc_mult_shift(&cs->mult, &cs->shift, freq,
|
||||
NSEC_PER_SEC/scale,
|
||||
MAX_UPDATE_LENGTH*scale);
|
||||
cs->max_idle_ns = clocksource_max_deferment(cs);
|
||||
/* Intialize mult/shift and max_idle_ns */
|
||||
__clocksource_updatefreq_scale(cs, scale, freq);
|
||||
|
||||
/* Add clocksource to the clcoksource list */
|
||||
mutex_lock(&clocksource_mutex);
|
||||
clocksource_enqueue(cs);
|
||||
clocksource_select();
|
||||
|
@@ -153,8 +153,8 @@ __cacheline_aligned_in_smp DEFINE_SEQLOCK(xtime_lock);
|
||||
* - wall_to_monotonic is no longer the boot time, getboottime must be
|
||||
* used instead.
|
||||
*/
|
||||
struct timespec xtime __attribute__ ((aligned (16)));
|
||||
struct timespec wall_to_monotonic __attribute__ ((aligned (16)));
|
||||
static struct timespec xtime __attribute__ ((aligned (16)));
|
||||
static struct timespec wall_to_monotonic __attribute__ ((aligned (16)));
|
||||
static struct timespec total_sleep_time;
|
||||
|
||||
/*
|
||||
@@ -170,11 +170,10 @@ void timekeeping_leap_insert(int leapsecond)
|
||||
{
|
||||
xtime.tv_sec += leapsecond;
|
||||
wall_to_monotonic.tv_sec -= leapsecond;
|
||||
update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult);
|
||||
update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock,
|
||||
timekeeper.mult);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_GENERIC_TIME
|
||||
|
||||
/**
|
||||
* timekeeping_forward_now - update clock to the current time
|
||||
*
|
||||
@@ -328,7 +327,8 @@ int do_settimeofday(struct timespec *tv)
|
||||
timekeeper.ntp_error = 0;
|
||||
ntp_clear();
|
||||
|
||||
update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult);
|
||||
update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock,
|
||||
timekeeper.mult);
|
||||
|
||||
write_sequnlock_irqrestore(&xtime_lock, flags);
|
||||
|
||||
@@ -376,52 +376,6 @@ void timekeeping_notify(struct clocksource *clock)
|
||||
tick_clock_notify();
|
||||
}
|
||||
|
||||
#else /* GENERIC_TIME */
|
||||
|
||||
static inline void timekeeping_forward_now(void) { }
|
||||
|
||||
/**
|
||||
* ktime_get - get the monotonic time in ktime_t format
|
||||
*
|
||||
* returns the time in ktime_t format
|
||||
*/
|
||||
ktime_t ktime_get(void)
|
||||
{
|
||||
struct timespec now;
|
||||
|
||||
ktime_get_ts(&now);
|
||||
|
||||
return timespec_to_ktime(now);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ktime_get);
|
||||
|
||||
/**
|
||||
* ktime_get_ts - get the monotonic clock in timespec format
|
||||
* @ts: pointer to timespec variable
|
||||
*
|
||||
* The function calculates the monotonic clock from the realtime
|
||||
* clock and the wall_to_monotonic offset and stores the result
|
||||
* in normalized timespec format in the variable pointed to by @ts.
|
||||
*/
|
||||
void ktime_get_ts(struct timespec *ts)
|
||||
{
|
||||
struct timespec tomono;
|
||||
unsigned long seq;
|
||||
|
||||
do {
|
||||
seq = read_seqbegin(&xtime_lock);
|
||||
getnstimeofday(ts);
|
||||
tomono = wall_to_monotonic;
|
||||
|
||||
} while (read_seqretry(&xtime_lock, seq));
|
||||
|
||||
set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec,
|
||||
ts->tv_nsec + tomono.tv_nsec);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ktime_get_ts);
|
||||
|
||||
#endif /* !GENERIC_TIME */
|
||||
|
||||
/**
|
||||
* ktime_get_real - get the real (wall-) time in ktime_t format
|
||||
*
|
||||
@@ -579,9 +533,9 @@ static int timekeeping_resume(struct sys_device *dev)
|
||||
|
||||
if (timespec_compare(&ts, &timekeeping_suspend_time) > 0) {
|
||||
ts = timespec_sub(ts, timekeeping_suspend_time);
|
||||
xtime = timespec_add_safe(xtime, ts);
|
||||
xtime = timespec_add(xtime, ts);
|
||||
wall_to_monotonic = timespec_sub(wall_to_monotonic, ts);
|
||||
total_sleep_time = timespec_add_safe(total_sleep_time, ts);
|
||||
total_sleep_time = timespec_add(total_sleep_time, ts);
|
||||
}
|
||||
/* re-base the last cycle value */
|
||||
timekeeper.clock->cycle_last = timekeeper.clock->read(timekeeper.clock);
|
||||
@@ -784,10 +738,11 @@ void update_wall_time(void)
|
||||
return;
|
||||
|
||||
clock = timekeeper.clock;
|
||||
#ifdef CONFIG_GENERIC_TIME
|
||||
offset = (clock->read(clock) - clock->cycle_last) & clock->mask;
|
||||
#else
|
||||
|
||||
#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
|
||||
offset = timekeeper.cycle_interval;
|
||||
#else
|
||||
offset = (clock->read(clock) - clock->cycle_last) & clock->mask;
|
||||
#endif
|
||||
timekeeper.xtime_nsec = (s64)xtime.tv_nsec << timekeeper.shift;
|
||||
|
||||
@@ -856,7 +811,8 @@ void update_wall_time(void)
|
||||
}
|
||||
|
||||
/* check to see if there is a new clocksource to use */
|
||||
update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult);
|
||||
update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock,
|
||||
timekeeper.mult);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -887,7 +843,7 @@ EXPORT_SYMBOL_GPL(getboottime);
|
||||
*/
|
||||
void monotonic_to_bootbased(struct timespec *ts)
|
||||
{
|
||||
*ts = timespec_add_safe(*ts, total_sleep_time);
|
||||
*ts = timespec_add(*ts, total_sleep_time);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(monotonic_to_bootbased);
|
||||
|
||||
@@ -902,6 +858,11 @@ struct timespec __current_kernel_time(void)
|
||||
return xtime;
|
||||
}
|
||||
|
||||
struct timespec __get_wall_to_monotonic(void)
|
||||
{
|
||||
return wall_to_monotonic;
|
||||
}
|
||||
|
||||
struct timespec current_kernel_time(void)
|
||||
{
|
||||
struct timespec now;
|
||||
|
Reference in New Issue
Block a user