Merge branch 'timers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'timers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: clocksource: Add clocksource_register_hz/khz interface posix-cpu-timers: Optimize run_posix_cpu_timers() time: Remove xtime_cache mqueue: Convert message queue timeout to use hrtimers hrtimers: Provide schedule_hrtimeout for CLOCK_REALTIME timers: Introduce the concept of timer slack for legacy timers ntp: Remove tickadj ntp: Make time_adjust static time: Add xtime, wall_to_monotonic to feature-removal-schedule timer: Try to survive timer callback preempt_count leak timer: Split out timer function call timer: Print function name for timer callbacks modifying preemption count time: Clean up warp_clock() cpu-timers: Avoid iterating over all threads in fastpath_timer_check() cpu-timers: Change SIGEV_NONE timer implementation cpu-timers: Return correct previous timer reload value cpu-timers: Cleanup arm_timer() cpu-timers: Simplify RLIMIT_CPU handling
This commit is contained in:
@@ -625,6 +625,54 @@ static void clocksource_enqueue(struct clocksource *cs)
|
||||
list_add(&cs->list, entry);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Maximum time we expect to go between ticks. This includes idle
|
||||
* tickless time. It provides the trade off between selecting a
|
||||
* mult/shift pair that is very precise but can only handle a short
|
||||
* period of time, vs. a mult/shift pair that can handle long periods
|
||||
* of time but isn't as precise.
|
||||
*
|
||||
* This is a subsystem constant, and actual hardware limitations
|
||||
* may override it (ie: clocksources that wrap every 3 seconds).
|
||||
*/
|
||||
#define MAX_UPDATE_LENGTH 5 /* Seconds */
|
||||
|
||||
/**
|
||||
* __clocksource_register_scale - Used to install new clocksources
|
||||
* @t: clocksource to be registered
|
||||
* @scale: Scale factor multiplied against freq to get clocksource hz
|
||||
* @freq: clocksource frequency (cycles per second) divided by scale
|
||||
*
|
||||
* Returns -EBUSY if registration fails, zero otherwise.
|
||||
*
|
||||
* This *SHOULD NOT* be called directly! Please use the
|
||||
* clocksource_register_hz() or clocksource_register_khz helper functions.
|
||||
*/
|
||||
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);
|
||||
|
||||
mutex_lock(&clocksource_mutex);
|
||||
clocksource_enqueue(cs);
|
||||
clocksource_select();
|
||||
clocksource_enqueue_watchdog(cs);
|
||||
mutex_unlock(&clocksource_mutex);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__clocksource_register_scale);
|
||||
|
||||
|
||||
/**
|
||||
* clocksource_register - Used to install new clocksources
|
||||
* @t: clocksource to be registered
|
||||
|
||||
+1
-1
@@ -69,7 +69,7 @@ static s64 time_freq;
|
||||
/* time at last adjustment (secs): */
|
||||
static long time_reftime;
|
||||
|
||||
long time_adjust;
|
||||
static long time_adjust;
|
||||
|
||||
/* constant (boot-param configurable) NTP tick adjustment (upscaled) */
|
||||
static s64 ntp_tick_adj;
|
||||
|
||||
+16
-19
@@ -165,13 +165,6 @@ struct timespec raw_time;
|
||||
/* flag for if timekeeping is suspended */
|
||||
int __read_mostly timekeeping_suspended;
|
||||
|
||||
static struct timespec xtime_cache __attribute__ ((aligned (16)));
|
||||
void update_xtime_cache(u64 nsec)
|
||||
{
|
||||
xtime_cache = xtime;
|
||||
timespec_add_ns(&xtime_cache, nsec);
|
||||
}
|
||||
|
||||
/* must hold xtime_lock */
|
||||
void timekeeping_leap_insert(int leapsecond)
|
||||
{
|
||||
@@ -332,8 +325,6 @@ int do_settimeofday(struct timespec *tv)
|
||||
|
||||
xtime = *tv;
|
||||
|
||||
update_xtime_cache(0);
|
||||
|
||||
timekeeper.ntp_error = 0;
|
||||
ntp_clear();
|
||||
|
||||
@@ -559,7 +550,6 @@ void __init timekeeping_init(void)
|
||||
}
|
||||
set_normalized_timespec(&wall_to_monotonic,
|
||||
-boot.tv_sec, -boot.tv_nsec);
|
||||
update_xtime_cache(0);
|
||||
total_sleep_time.tv_sec = 0;
|
||||
total_sleep_time.tv_nsec = 0;
|
||||
write_sequnlock_irqrestore(&xtime_lock, flags);
|
||||
@@ -593,7 +583,6 @@ static int timekeeping_resume(struct sys_device *dev)
|
||||
wall_to_monotonic = timespec_sub(wall_to_monotonic, ts);
|
||||
total_sleep_time = timespec_add_safe(total_sleep_time, ts);
|
||||
}
|
||||
update_xtime_cache(0);
|
||||
/* re-base the last cycle value */
|
||||
timekeeper.clock->cycle_last = timekeeper.clock->read(timekeeper.clock);
|
||||
timekeeper.ntp_error = 0;
|
||||
@@ -788,7 +777,6 @@ void update_wall_time(void)
|
||||
{
|
||||
struct clocksource *clock;
|
||||
cycle_t offset;
|
||||
u64 nsecs;
|
||||
int shift = 0, maxshift;
|
||||
|
||||
/* Make sure we're fully resumed: */
|
||||
@@ -847,7 +835,9 @@ void update_wall_time(void)
|
||||
timekeeper.ntp_error += neg << timekeeper.ntp_error_shift;
|
||||
}
|
||||
|
||||
/* store full nanoseconds into xtime after rounding it up and
|
||||
|
||||
/*
|
||||
* Store full nanoseconds into xtime after rounding it up and
|
||||
* add the remainder to the error difference.
|
||||
*/
|
||||
xtime.tv_nsec = ((s64) timekeeper.xtime_nsec >> timekeeper.shift) + 1;
|
||||
@@ -855,8 +845,15 @@ void update_wall_time(void)
|
||||
timekeeper.ntp_error += timekeeper.xtime_nsec <<
|
||||
timekeeper.ntp_error_shift;
|
||||
|
||||
nsecs = clocksource_cyc2ns(offset, timekeeper.mult, timekeeper.shift);
|
||||
update_xtime_cache(nsecs);
|
||||
/*
|
||||
* Finally, make sure that after the rounding
|
||||
* xtime.tv_nsec isn't larger then NSEC_PER_SEC
|
||||
*/
|
||||
if (unlikely(xtime.tv_nsec >= NSEC_PER_SEC)) {
|
||||
xtime.tv_nsec -= NSEC_PER_SEC;
|
||||
xtime.tv_sec++;
|
||||
second_overflow();
|
||||
}
|
||||
|
||||
/* check to see if there is a new clocksource to use */
|
||||
update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult);
|
||||
@@ -896,13 +893,13 @@ EXPORT_SYMBOL_GPL(monotonic_to_bootbased);
|
||||
|
||||
unsigned long get_seconds(void)
|
||||
{
|
||||
return xtime_cache.tv_sec;
|
||||
return xtime.tv_sec;
|
||||
}
|
||||
EXPORT_SYMBOL(get_seconds);
|
||||
|
||||
struct timespec __current_kernel_time(void)
|
||||
{
|
||||
return xtime_cache;
|
||||
return xtime;
|
||||
}
|
||||
|
||||
struct timespec current_kernel_time(void)
|
||||
@@ -913,7 +910,7 @@ struct timespec current_kernel_time(void)
|
||||
do {
|
||||
seq = read_seqbegin(&xtime_lock);
|
||||
|
||||
now = xtime_cache;
|
||||
now = xtime;
|
||||
} while (read_seqretry(&xtime_lock, seq));
|
||||
|
||||
return now;
|
||||
@@ -928,7 +925,7 @@ struct timespec get_monotonic_coarse(void)
|
||||
do {
|
||||
seq = read_seqbegin(&xtime_lock);
|
||||
|
||||
now = xtime_cache;
|
||||
now = xtime;
|
||||
mono = wall_to_monotonic;
|
||||
} while (read_seqretry(&xtime_lock, seq));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user