Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer core updates from Thomas Gleixner. * 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: ia64: vsyscall: Add missing paranthesis alarmtimer: Don't call rtc_timer_init() when CONFIG_RTC_CLASS=n x86: vdso: Put declaration before code x86-64: Inline vdso clock_gettime helpers x86-64: Simplify and optimize vdso clock_gettime monotonic variants kernel-time: fix s/then/than/ spelling errors time: remove no_sync_cmos_clock time: Avoid scary backtraces when warning of > 11% adj alarmtimer: Make sure we initialize the rtctimer ntp: Fix leap-second hrtimer livelock x86, tsc: Skip refined tsc calibration on systems with reliable TSC rtc: Provide flag for rtc devices that don't support UIE ia64: vsyscall: Use seqcount instead of seqlock x86: vdso: Use seqcount instead of seqlock x86: vdso: Remove bogus locking in update_vsyscall_tz() time: Remove bogus comments time: Fix change_clocksource locking time: x86: Fix race switching from vsyscall to non-vsyscall clock
This commit is contained in:
@@ -163,7 +163,6 @@ int do_sys_settimeofday(const struct timespec *tv, const struct timezone *tz)
|
||||
return error;
|
||||
|
||||
if (tz) {
|
||||
/* SMP safe, global irq locking makes it work. */
|
||||
sys_tz = *tz;
|
||||
update_vsyscall_tz();
|
||||
if (firsttime) {
|
||||
@@ -173,12 +172,7 @@ int do_sys_settimeofday(const struct timespec *tv, const struct timezone *tz)
|
||||
}
|
||||
}
|
||||
if (tv)
|
||||
{
|
||||
/* SMP safe, again the code in arch/foo/time.c should
|
||||
* globally block out interrupts when it runs.
|
||||
*/
|
||||
return do_settimeofday(tv);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -96,6 +96,11 @@ static int alarmtimer_rtc_add_device(struct device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void alarmtimer_rtc_timer_init(void)
|
||||
{
|
||||
rtc_timer_init(&rtctimer, NULL, NULL);
|
||||
}
|
||||
|
||||
static struct class_interface alarmtimer_rtc_interface = {
|
||||
.add_dev = &alarmtimer_rtc_add_device,
|
||||
};
|
||||
@@ -117,6 +122,7 @@ static inline struct rtc_device *alarmtimer_get_rtcdev(void)
|
||||
#define rtcdev (NULL)
|
||||
static inline int alarmtimer_rtc_interface_setup(void) { return 0; }
|
||||
static inline void alarmtimer_rtc_interface_remove(void) { }
|
||||
static inline void alarmtimer_rtc_timer_init(void) { }
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -783,6 +789,8 @@ static int __init alarmtimer_init(void)
|
||||
.nsleep = alarm_timer_nsleep,
|
||||
};
|
||||
|
||||
alarmtimer_rtc_timer_init();
|
||||
|
||||
posix_timers_register_clock(CLOCK_REALTIME_ALARM, &alarm_clock);
|
||||
posix_timers_register_clock(CLOCK_BOOTTIME_ALARM, &alarm_clock);
|
||||
|
||||
|
@@ -500,7 +500,7 @@ static u32 clocksource_max_adjustment(struct clocksource *cs)
|
||||
{
|
||||
u64 ret;
|
||||
/*
|
||||
* We won't try to correct for more then 11% adjustments (110,000 ppm),
|
||||
* We won't try to correct for more than 11% adjustments (110,000 ppm),
|
||||
*/
|
||||
ret = (u64)cs->mult * 11;
|
||||
do_div(ret,100);
|
||||
|
@@ -34,8 +34,6 @@ unsigned long tick_nsec;
|
||||
static u64 tick_length;
|
||||
static u64 tick_length_base;
|
||||
|
||||
static struct hrtimer leap_timer;
|
||||
|
||||
#define MAX_TICKADJ 500LL /* usecs */
|
||||
#define MAX_TICKADJ_SCALED \
|
||||
(((MAX_TICKADJ * NSEC_PER_USEC) << NTP_SCALE_SHIFT) / NTP_INTERVAL_FREQ)
|
||||
@@ -380,57 +378,6 @@ u64 ntp_tick_length(void)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Leap second processing. If in leap-insert state at the end of the
|
||||
* day, the system clock is set back one second; if in leap-delete
|
||||
* state, the system clock is set ahead one second.
|
||||
*/
|
||||
static enum hrtimer_restart ntp_leap_second(struct hrtimer *timer)
|
||||
{
|
||||
enum hrtimer_restart res = HRTIMER_NORESTART;
|
||||
unsigned long flags;
|
||||
int leap = 0;
|
||||
|
||||
spin_lock_irqsave(&ntp_lock, flags);
|
||||
switch (time_state) {
|
||||
case TIME_OK:
|
||||
break;
|
||||
case TIME_INS:
|
||||
leap = -1;
|
||||
time_state = TIME_OOP;
|
||||
printk(KERN_NOTICE
|
||||
"Clock: inserting leap second 23:59:60 UTC\n");
|
||||
hrtimer_add_expires_ns(&leap_timer, NSEC_PER_SEC);
|
||||
res = HRTIMER_RESTART;
|
||||
break;
|
||||
case TIME_DEL:
|
||||
leap = 1;
|
||||
time_tai--;
|
||||
time_state = TIME_WAIT;
|
||||
printk(KERN_NOTICE
|
||||
"Clock: deleting leap second 23:59:59 UTC\n");
|
||||
break;
|
||||
case TIME_OOP:
|
||||
time_tai++;
|
||||
time_state = TIME_WAIT;
|
||||
/* fall through */
|
||||
case TIME_WAIT:
|
||||
if (!(time_status & (STA_INS | STA_DEL)))
|
||||
time_state = TIME_OK;
|
||||
break;
|
||||
}
|
||||
spin_unlock_irqrestore(&ntp_lock, flags);
|
||||
|
||||
/*
|
||||
* We have to call this outside of the ntp_lock to keep
|
||||
* the proper locking hierarchy
|
||||
*/
|
||||
if (leap)
|
||||
timekeeping_leap_insert(leap);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* this routine handles the overflow of the microsecond field
|
||||
*
|
||||
@@ -438,14 +385,58 @@ static enum hrtimer_restart ntp_leap_second(struct hrtimer *timer)
|
||||
* were provided by Dave Mills (Mills@UDEL.EDU) of NTP fame.
|
||||
* They were originally developed for SUN and DEC kernels.
|
||||
* All the kudos should go to Dave for this stuff.
|
||||
*
|
||||
* Also handles leap second processing, and returns leap offset
|
||||
*/
|
||||
void second_overflow(void)
|
||||
int second_overflow(unsigned long secs)
|
||||
{
|
||||
s64 delta;
|
||||
int leap = 0;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ntp_lock, flags);
|
||||
|
||||
/*
|
||||
* Leap second processing. If in leap-insert state at the end of the
|
||||
* day, the system clock is set back one second; if in leap-delete
|
||||
* state, the system clock is set ahead one second.
|
||||
*/
|
||||
switch (time_state) {
|
||||
case TIME_OK:
|
||||
if (time_status & STA_INS)
|
||||
time_state = TIME_INS;
|
||||
else if (time_status & STA_DEL)
|
||||
time_state = TIME_DEL;
|
||||
break;
|
||||
case TIME_INS:
|
||||
if (secs % 86400 == 0) {
|
||||
leap = -1;
|
||||
time_state = TIME_OOP;
|
||||
printk(KERN_NOTICE
|
||||
"Clock: inserting leap second 23:59:60 UTC\n");
|
||||
}
|
||||
break;
|
||||
case TIME_DEL:
|
||||
if ((secs + 1) % 86400 == 0) {
|
||||
leap = 1;
|
||||
time_tai--;
|
||||
time_state = TIME_WAIT;
|
||||
printk(KERN_NOTICE
|
||||
"Clock: deleting leap second 23:59:59 UTC\n");
|
||||
}
|
||||
break;
|
||||
case TIME_OOP:
|
||||
time_tai++;
|
||||
time_state = TIME_WAIT;
|
||||
break;
|
||||
|
||||
case TIME_WAIT:
|
||||
if (!(time_status & (STA_INS | STA_DEL)))
|
||||
time_state = TIME_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* Bump the maxerror field */
|
||||
time_maxerror += MAXFREQ / NSEC_PER_USEC;
|
||||
if (time_maxerror > NTP_PHASE_LIMIT) {
|
||||
@@ -481,15 +472,17 @@ void second_overflow(void)
|
||||
tick_length += (s64)(time_adjust * NSEC_PER_USEC / NTP_INTERVAL_FREQ)
|
||||
<< NTP_SCALE_SHIFT;
|
||||
time_adjust = 0;
|
||||
|
||||
|
||||
|
||||
out:
|
||||
spin_unlock_irqrestore(&ntp_lock, flags);
|
||||
|
||||
return leap;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_GENERIC_CMOS_UPDATE
|
||||
|
||||
/* Disable the cmos update - used by virtualization and embedded */
|
||||
int no_sync_cmos_clock __read_mostly;
|
||||
|
||||
static void sync_cmos_clock(struct work_struct *work);
|
||||
|
||||
static DECLARE_DELAYED_WORK(sync_cmos_work, sync_cmos_clock);
|
||||
@@ -536,35 +529,13 @@ static void sync_cmos_clock(struct work_struct *work)
|
||||
|
||||
static void notify_cmos_timer(void)
|
||||
{
|
||||
if (!no_sync_cmos_clock)
|
||||
schedule_delayed_work(&sync_cmos_work, 0);
|
||||
schedule_delayed_work(&sync_cmos_work, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
static inline void notify_cmos_timer(void) { }
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Start the leap seconds timer:
|
||||
*/
|
||||
static inline void ntp_start_leap_timer(struct timespec *ts)
|
||||
{
|
||||
long now = ts->tv_sec;
|
||||
|
||||
if (time_status & STA_INS) {
|
||||
time_state = TIME_INS;
|
||||
now += 86400 - now % 86400;
|
||||
hrtimer_start(&leap_timer, ktime_set(now, 0), HRTIMER_MODE_ABS);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (time_status & STA_DEL) {
|
||||
time_state = TIME_DEL;
|
||||
now += 86400 - (now + 1) % 86400;
|
||||
hrtimer_start(&leap_timer, ktime_set(now, 0), HRTIMER_MODE_ABS);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Propagate a new txc->status value into the NTP state:
|
||||
@@ -589,22 +560,6 @@ static inline void process_adj_status(struct timex *txc, struct timespec *ts)
|
||||
time_status &= STA_RONLY;
|
||||
time_status |= txc->status & ~STA_RONLY;
|
||||
|
||||
switch (time_state) {
|
||||
case TIME_OK:
|
||||
ntp_start_leap_timer(ts);
|
||||
break;
|
||||
case TIME_INS:
|
||||
case TIME_DEL:
|
||||
time_state = TIME_OK;
|
||||
ntp_start_leap_timer(ts);
|
||||
case TIME_WAIT:
|
||||
if (!(time_status & (STA_INS | STA_DEL)))
|
||||
time_state = TIME_OK;
|
||||
break;
|
||||
case TIME_OOP:
|
||||
hrtimer_restart(&leap_timer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Called with the xtime lock held, so we can access and modify
|
||||
@@ -686,9 +641,6 @@ int do_adjtimex(struct timex *txc)
|
||||
(txc->tick < 900000/USER_HZ ||
|
||||
txc->tick > 1100000/USER_HZ))
|
||||
return -EINVAL;
|
||||
|
||||
if (txc->modes & ADJ_STATUS && time_state != TIME_OK)
|
||||
hrtimer_cancel(&leap_timer);
|
||||
}
|
||||
|
||||
if (txc->modes & ADJ_SETOFFSET) {
|
||||
@@ -1010,6 +962,4 @@ __setup("ntp_tick_adj=", ntp_tick_adj_setup);
|
||||
void __init ntp_init(void)
|
||||
{
|
||||
ntp_clear();
|
||||
hrtimer_init(&leap_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
|
||||
leap_timer.function = ntp_leap_second;
|
||||
}
|
||||
|
@@ -184,18 +184,6 @@ static void timekeeping_update(bool clearntp)
|
||||
}
|
||||
|
||||
|
||||
void timekeeping_leap_insert(int leapsecond)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
write_seqlock_irqsave(&timekeeper.lock, flags);
|
||||
timekeeper.xtime.tv_sec += leapsecond;
|
||||
timekeeper.wall_to_monotonic.tv_sec -= leapsecond;
|
||||
timekeeping_update(false);
|
||||
write_sequnlock_irqrestore(&timekeeper.lock, flags);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* timekeeping_forward_now - update clock to the current time
|
||||
*
|
||||
@@ -448,9 +436,12 @@ EXPORT_SYMBOL(timekeeping_inject_offset);
|
||||
static int change_clocksource(void *data)
|
||||
{
|
||||
struct clocksource *new, *old;
|
||||
unsigned long flags;
|
||||
|
||||
new = (struct clocksource *) data;
|
||||
|
||||
write_seqlock_irqsave(&timekeeper.lock, flags);
|
||||
|
||||
timekeeping_forward_now();
|
||||
if (!new->enable || new->enable(new) == 0) {
|
||||
old = timekeeper.clock;
|
||||
@@ -458,6 +449,10 @@ static int change_clocksource(void *data)
|
||||
if (old->disable)
|
||||
old->disable(old);
|
||||
}
|
||||
timekeeping_update(true);
|
||||
|
||||
write_sequnlock_irqrestore(&timekeeper.lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -827,7 +822,7 @@ static void timekeeping_adjust(s64 offset)
|
||||
int adj;
|
||||
|
||||
/*
|
||||
* The point of this is to check if the error is greater then half
|
||||
* The point of this is to check if the error is greater than half
|
||||
* an interval.
|
||||
*
|
||||
* First we shift it down from NTP_SHIFT to clocksource->shifted nsecs.
|
||||
@@ -835,7 +830,7 @@ static void timekeeping_adjust(s64 offset)
|
||||
* Note we subtract one in the shift, so that error is really error*2.
|
||||
* This "saves" dividing(shifting) interval twice, but keeps the
|
||||
* (error > interval) comparison as still measuring if error is
|
||||
* larger then half an interval.
|
||||
* larger than half an interval.
|
||||
*
|
||||
* Note: It does not "save" on aggravation when reading the code.
|
||||
*/
|
||||
@@ -843,7 +838,7 @@ static void timekeeping_adjust(s64 offset)
|
||||
if (error > interval) {
|
||||
/*
|
||||
* We now divide error by 4(via shift), which checks if
|
||||
* the error is greater then twice the interval.
|
||||
* the error is greater than twice the interval.
|
||||
* If it is greater, we need a bigadjust, if its smaller,
|
||||
* we can adjust by 1.
|
||||
*/
|
||||
@@ -874,13 +869,15 @@ static void timekeeping_adjust(s64 offset)
|
||||
} else /* No adjustment needed */
|
||||
return;
|
||||
|
||||
WARN_ONCE(timekeeper.clock->maxadj &&
|
||||
(timekeeper.mult + adj > timekeeper.clock->mult +
|
||||
timekeeper.clock->maxadj),
|
||||
"Adjusting %s more then 11%% (%ld vs %ld)\n",
|
||||
if (unlikely(timekeeper.clock->maxadj &&
|
||||
(timekeeper.mult + adj >
|
||||
timekeeper.clock->mult + timekeeper.clock->maxadj))) {
|
||||
printk_once(KERN_WARNING
|
||||
"Adjusting %s more than 11%% (%ld vs %ld)\n",
|
||||
timekeeper.clock->name, (long)timekeeper.mult + adj,
|
||||
(long)timekeeper.clock->mult +
|
||||
timekeeper.clock->maxadj);
|
||||
}
|
||||
/*
|
||||
* So the following can be confusing.
|
||||
*
|
||||
@@ -952,7 +949,7 @@ static cycle_t logarithmic_accumulation(cycle_t offset, int shift)
|
||||
u64 nsecps = (u64)NSEC_PER_SEC << timekeeper.shift;
|
||||
u64 raw_nsecs;
|
||||
|
||||
/* If the offset is smaller then a shifted interval, do nothing */
|
||||
/* If the offset is smaller than a shifted interval, do nothing */
|
||||
if (offset < timekeeper.cycle_interval<<shift)
|
||||
return offset;
|
||||
|
||||
@@ -962,9 +959,11 @@ static cycle_t logarithmic_accumulation(cycle_t offset, int shift)
|
||||
|
||||
timekeeper.xtime_nsec += timekeeper.xtime_interval << shift;
|
||||
while (timekeeper.xtime_nsec >= nsecps) {
|
||||
int leap;
|
||||
timekeeper.xtime_nsec -= nsecps;
|
||||
timekeeper.xtime.tv_sec++;
|
||||
second_overflow();
|
||||
leap = second_overflow(timekeeper.xtime.tv_sec);
|
||||
timekeeper.xtime.tv_sec += leap;
|
||||
}
|
||||
|
||||
/* Accumulate raw time */
|
||||
@@ -1018,13 +1017,13 @@ static void update_wall_time(void)
|
||||
* With NO_HZ we may have to accumulate many cycle_intervals
|
||||
* (think "ticks") worth of time at once. To do this efficiently,
|
||||
* we calculate the largest doubling multiple of cycle_intervals
|
||||
* that is smaller then the offset. We then accumulate that
|
||||
* that is smaller than the offset. We then accumulate that
|
||||
* chunk in one go, and then try to consume the next smaller
|
||||
* doubled multiple.
|
||||
*/
|
||||
shift = ilog2(offset) - ilog2(timekeeper.cycle_interval);
|
||||
shift = max(0, shift);
|
||||
/* Bound shift to one less then what overflows tick_length */
|
||||
/* Bound shift to one less than what overflows tick_length */
|
||||
maxshift = (64 - (ilog2(ntp_tick_length())+1)) - 1;
|
||||
shift = min(shift, maxshift);
|
||||
while (offset >= timekeeper.cycle_interval) {
|
||||
@@ -1072,12 +1071,14 @@ static void update_wall_time(void)
|
||||
|
||||
/*
|
||||
* Finally, make sure that after the rounding
|
||||
* xtime.tv_nsec isn't larger then NSEC_PER_SEC
|
||||
* xtime.tv_nsec isn't larger than NSEC_PER_SEC
|
||||
*/
|
||||
if (unlikely(timekeeper.xtime.tv_nsec >= NSEC_PER_SEC)) {
|
||||
int leap;
|
||||
timekeeper.xtime.tv_nsec -= NSEC_PER_SEC;
|
||||
timekeeper.xtime.tv_sec++;
|
||||
second_overflow();
|
||||
leap = second_overflow(timekeeper.xtime.tv_sec);
|
||||
timekeeper.xtime.tv_sec += leap;
|
||||
}
|
||||
|
||||
timekeeping_update(false);
|
||||
|
Reference in New Issue
Block a user