2006-10-01 10:28:22 +04:00
/*
* linux / kernel / time / ntp . c
*
* NTP state machine interfaces and logic .
*
* This code was mainly moved from kernel / timer . c and kernel / time . c
* Please see those files for relevant copyright info and historical
* changelogs .
*/
# include <linux/mm.h>
# include <linux/time.h>
2007-07-21 15:37:37 +04:00
# include <linux/timer.h>
2006-10-01 10:28:22 +04:00
# include <linux/timex.h>
Detach sched.h from mm.h
First thing mm.h does is including sched.h solely for can_do_mlock() inline
function which has "current" dereference inside. By dealing with can_do_mlock()
mm.h can be detached from sched.h which is good. See below, why.
This patch
a) removes unconditional inclusion of sched.h from mm.h
b) makes can_do_mlock() normal function in mm/mlock.c
c) exports can_do_mlock() to not break compilation
d) adds sched.h inclusions back to files that were getting it indirectly.
e) adds less bloated headers to some files (asm/signal.h, jiffies.h) that were
getting them indirectly
Net result is:
a) mm.h users would get less code to open, read, preprocess, parse, ... if
they don't need sched.h
b) sched.h stops being dependency for significant number of files:
on x86_64 allmodconfig touching sched.h results in recompile of 4083 files,
after patch it's only 3744 (-8.3%).
Cross-compile tested on
all arm defconfigs, all mips defconfigs, all powerpc defconfigs,
alpha alpha-up
arm
i386 i386-up i386-defconfig i386-allnoconfig
ia64 ia64-up
m68k
mips
parisc parisc-up
powerpc powerpc-up
s390 s390-up
sparc sparc-up
sparc64 sparc64-up
um-x86_64
x86_64 x86_64-up x86_64-defconfig x86_64-allnoconfig
as well as my two usual configs.
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-05-21 01:22:52 +04:00
# include <linux/jiffies.h>
# include <linux/hrtimer.h>
2007-07-16 10:40:39 +04:00
# include <linux/capability.h>
2006-10-01 10:28:22 +04:00
# include <asm/div64.h>
# include <asm/timex.h>
2006-10-01 10:28:22 +04:00
/*
* Timekeeping variables
*/
unsigned long tick_usec = TICK_USEC ; /* USER_HZ period (usec) */
unsigned long tick_nsec ; /* ACTHZ period (nsec) */
static u64 tick_length , tick_length_base ;
2006-10-01 10:28:25 +04:00
# define MAX_TICKADJ 500 /* microsecs */
# define MAX_TICKADJ_SCALED (((u64)(MAX_TICKADJ * NSEC_PER_USEC) << \
2007-02-16 12:27:26 +03:00
TICK_LENGTH_SHIFT ) / NTP_INTERVAL_FREQ )
2006-10-01 10:28:22 +04:00
/*
* phase - lock loop variables
*/
/* TIME_ERROR prevents overwriting the CMOS clock */
2006-10-01 10:28:29 +04:00
static int time_state = TIME_OK ; /* clock synchronization status */
2006-10-01 10:28:22 +04:00
int time_status = STA_UNSYNC ; /* clock status bits */
2007-03-27 09:32:26 +04:00
static s64 time_offset ; /* time adjustment (ns) */
2006-10-01 10:28:29 +04:00
static long time_constant = 2 ; /* pll time constant */
2006-10-01 10:28:22 +04:00
long time_maxerror = NTP_PHASE_LIMIT ; /* maximum error (us) */
long time_esterror = NTP_PHASE_LIMIT ; /* estimated error (us) */
2006-10-01 10:28:24 +04:00
long time_freq ; /* frequency offset (scaled ppm)*/
2006-10-01 10:28:29 +04:00
static long time_reftime ; /* time at last adjustment (s) */
2006-10-01 10:28:22 +04:00
long time_adjust ;
2006-10-01 10:28:29 +04:00
# define CLOCK_TICK_OVERFLOW (LATCH * HZ - CLOCK_TICK_RATE)
# define CLOCK_TICK_ADJUST (((s64)CLOCK_TICK_OVERFLOW * NSEC_PER_SEC) / \
( s64 ) CLOCK_TICK_RATE )
static void ntp_update_frequency ( void )
{
2007-02-16 12:27:26 +03:00
u64 second_length = ( u64 ) ( tick_usec * NSEC_PER_USEC * USER_HZ )
< < TICK_LENGTH_SHIFT ;
second_length + = ( s64 ) CLOCK_TICK_ADJUST < < TICK_LENGTH_SHIFT ;
second_length + = ( s64 ) time_freq < < ( TICK_LENGTH_SHIFT - SHIFT_NSEC ) ;
2006-10-01 10:28:29 +04:00
2007-02-16 12:27:26 +03:00
tick_length_base = second_length ;
2006-10-01 10:28:29 +04:00
2007-02-16 12:27:26 +03:00
do_div ( second_length , HZ ) ;
tick_nsec = second_length > > TICK_LENGTH_SHIFT ;
do_div ( tick_length_base , NTP_INTERVAL_FREQ ) ;
2006-10-01 10:28:29 +04:00
}
2006-10-01 10:28:22 +04:00
/**
* ntp_clear - Clears the NTP state variables
*
* Must be called while holding a write on the xtime_lock
*/
void ntp_clear ( void )
{
time_adjust = 0 ; /* stop active adjtime() */
time_status | = STA_UNSYNC ;
time_maxerror = NTP_PHASE_LIMIT ;
time_esterror = NTP_PHASE_LIMIT ;
ntp_update_frequency ( ) ;
tick_length = tick_length_base ;
2006-10-01 10:28:25 +04:00
time_offset = 0 ;
2006-10-01 10:28:22 +04:00
}
2006-10-01 10:28:22 +04:00
/*
* this routine handles the overflow of the microsecond field
*
* The tricky bits of code to handle the accurate clock support
* 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 .
*/
void second_overflow ( void )
{
2006-10-01 10:28:25 +04:00
long time_adj ;
2006-10-01 10:28:22 +04:00
/* Bump the maxerror field */
2006-10-01 10:28:26 +04:00
time_maxerror + = MAXFREQ > > SHIFT_USEC ;
2006-10-01 10:28:22 +04:00
if ( time_maxerror > NTP_PHASE_LIMIT ) {
time_maxerror = NTP_PHASE_LIMIT ;
time_status | = STA_UNSYNC ;
}
/*
* 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 . The microtime ( )
* routine or external clock driver will insure that reported time is
* always monotonic . The ugly divides should be replaced .
*/
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 ( xtime . tv_sec % 86400 = = 0 ) {
xtime . tv_sec - - ;
wall_to_monotonic . tv_sec + + ;
time_state = TIME_OOP ;
printk ( KERN_NOTICE " Clock: inserting leap second "
" 23:59:60 UTC \n " ) ;
}
break ;
case TIME_DEL :
if ( ( xtime . tv_sec + 1 ) % 86400 = = 0 ) {
xtime . tv_sec + + ;
wall_to_monotonic . tv_sec - - ;
time_state = TIME_WAIT ;
printk ( KERN_NOTICE " Clock: deleting leap second "
" 23:59:59 UTC \n " ) ;
}
break ;
case TIME_OOP :
time_state = TIME_WAIT ;
break ;
case TIME_WAIT :
if ( ! ( time_status & ( STA_INS | STA_DEL ) ) )
time_state = TIME_OK ;
}
/*
2006-10-01 10:28:28 +04:00
* Compute the phase adjustment for the next second . The offset is
* reduced by a fixed factor times the time constant .
2006-10-01 10:28:22 +04:00
*/
2006-10-01 10:28:22 +04:00
tick_length = tick_length_base ;
2006-10-01 10:28:28 +04:00
time_adj = shift_right ( time_offset , SHIFT_PLL + time_constant ) ;
2006-10-01 10:28:25 +04:00
time_offset - = time_adj ;
tick_length + = ( s64 ) time_adj < < ( TICK_LENGTH_SHIFT - SHIFT_UPDATE ) ;
2006-10-01 10:28:22 +04:00
2006-10-01 10:28:25 +04:00
if ( unlikely ( time_adjust ) ) {
if ( time_adjust > MAX_TICKADJ ) {
time_adjust - = MAX_TICKADJ ;
tick_length + = MAX_TICKADJ_SCALED ;
} else if ( time_adjust < - MAX_TICKADJ ) {
time_adjust + = MAX_TICKADJ ;
tick_length - = MAX_TICKADJ_SCALED ;
} else {
tick_length + = ( s64 ) ( time_adjust * NSEC_PER_USEC /
2007-02-16 12:27:26 +03:00
NTP_INTERVAL_FREQ ) < < TICK_LENGTH_SHIFT ;
2006-10-28 21:38:56 +04:00
time_adjust = 0 ;
2006-10-01 10:28:25 +04:00
}
2006-10-01 10:28:22 +04:00
}
}
/*
* Return how long ticks are at the moment , that is , how much time
* update_wall_time_one_tick will add to xtime next time we call it
* ( assuming no calls to do_adjtimex in the meantime ) .
* The return value is in fixed - point nanoseconds shifted by the
* specified number of bits to the right of the binary point .
* This function has no side - effects .
*/
u64 current_tick_length ( void )
{
2006-10-01 10:28:25 +04:00
return tick_length ;
2006-10-01 10:28:22 +04:00
}
2007-07-21 15:37:37 +04:00
# ifdef CONFIG_GENERIC_CMOS_UPDATE
2006-10-01 10:28:22 +04:00
2007-07-21 15:37:37 +04:00
/* Disable the cmos update - used by virtualization and embedded */
int no_sync_cmos_clock __read_mostly ;
static void sync_cmos_clock ( unsigned long dummy ) ;
static DEFINE_TIMER ( sync_cmos_timer , sync_cmos_clock , 0 , 0 ) ;
static void sync_cmos_clock ( unsigned long dummy )
{
struct timespec now , next ;
int fail = 1 ;
/*
* If we have an externally synchronized Linux clock , then update
* CMOS clock accordingly every ~ 11 minutes . Set_rtc_mmss ( ) has to be
* called as close as possible to 500 ms before the new second starts .
* This code is run on a timer . If the clock is set , that timer
* may not expire at the correct time . Thus , we adjust . . .
*/
if ( ! ntp_synced ( ) )
/*
* Not synced , exit , do not restart a timer ( if one is
* running , let it run out ) .
*/
return ;
getnstimeofday ( & now ) ;
if ( abs ( xtime . tv_nsec - ( NSEC_PER_SEC / 2 ) ) < = tick_nsec / 2 )
fail = update_persistent_clock ( now ) ;
next . tv_nsec = ( NSEC_PER_SEC / 2 ) - now . tv_nsec ;
if ( next . tv_nsec < = 0 )
next . tv_nsec + = NSEC_PER_SEC ;
if ( ! fail )
next . tv_sec = 659 ;
else
next . tv_sec = 0 ;
if ( next . tv_nsec > = NSEC_PER_SEC ) {
next . tv_sec + + ;
next . tv_nsec - = NSEC_PER_SEC ;
}
mod_timer ( & sync_cmos_timer , jiffies + timespec_to_jiffies ( & next ) ) ;
}
static void notify_cmos_timer ( void )
2006-10-01 10:28:22 +04:00
{
2007-07-21 15:37:37 +04:00
if ( no_sync_cmos_clock )
mod_timer ( & sync_cmos_timer , jiffies + 1 ) ;
2006-10-01 10:28:22 +04:00
}
2007-07-21 15:37:37 +04:00
# else
static inline void notify_cmos_timer ( void ) { }
# endif
2006-10-01 10:28:22 +04:00
/* adjtimex mainly allows reading (and writing, if superuser) of
* kernel time - keeping variables . used by xntpd .
*/
int do_adjtimex ( struct timex * txc )
{
2007-03-27 09:32:26 +04:00
long mtemp , save_adjust , rem ;
2006-10-01 10:28:28 +04:00
s64 freq_adj , temp64 ;
2006-10-01 10:28:22 +04:00
int result ;
/* In order to modify anything, you gotta be super-user! */
if ( txc - > modes & & ! capable ( CAP_SYS_TIME ) )
return - EPERM ;
/* Now we validate the data before disabling interrupts */
if ( ( txc - > modes & ADJ_OFFSET_SINGLESHOT ) = = ADJ_OFFSET_SINGLESHOT )
/* singleshot must not be used with any other mode bits */
if ( txc - > modes ! = ADJ_OFFSET_SINGLESHOT )
return - EINVAL ;
if ( txc - > modes ! = ADJ_OFFSET_SINGLESHOT & & ( txc - > modes & ADJ_OFFSET ) )
/* adjustment Offset limited to +- .512 seconds */
if ( txc - > offset < = - MAXPHASE | | txc - > offset > = MAXPHASE )
return - EINVAL ;
/* if the quartz is off by more than 10% something is VERY wrong ! */
if ( txc - > modes & ADJ_TICK )
if ( txc - > tick < 900000 / USER_HZ | |
txc - > tick > 1100000 / USER_HZ )
return - EINVAL ;
write_seqlock_irq ( & xtime_lock ) ;
result = time_state ; /* mostly `TIME_OK' */
/* Save for later - semantics of adjtime is to return old value */
2006-10-01 10:28:25 +04:00
save_adjust = time_adjust ;
2006-10-01 10:28:22 +04:00
#if 0 /* STA_CLOCKERR is never set yet */
time_status & = ~ STA_CLOCKERR ; /* reset STA_CLOCKERR */
# endif
/* If there are input parameters, then process them */
if ( txc - > modes )
{
if ( txc - > modes & ADJ_STATUS ) /* only set allowed bits */
time_status = ( txc - > status & ~ STA_RONLY ) |
( time_status & STA_RONLY ) ;
if ( txc - > modes & ADJ_FREQUENCY ) { /* p. 22 */
if ( txc - > freq > MAXFREQ | | txc - > freq < - MAXFREQ ) {
result = - EINVAL ;
goto leave ;
}
2007-02-16 12:27:26 +03:00
time_freq = ( ( s64 ) txc - > freq * NSEC_PER_USEC )
> > ( SHIFT_USEC - SHIFT_NSEC ) ;
2006-10-01 10:28:22 +04:00
}
if ( txc - > modes & ADJ_MAXERROR ) {
if ( txc - > maxerror < 0 | | txc - > maxerror > = NTP_PHASE_LIMIT ) {
result = - EINVAL ;
goto leave ;
}
time_maxerror = txc - > maxerror ;
}
if ( txc - > modes & ADJ_ESTERROR ) {
if ( txc - > esterror < 0 | | txc - > esterror > = NTP_PHASE_LIMIT ) {
result = - EINVAL ;
goto leave ;
}
time_esterror = txc - > esterror ;
}
if ( txc - > modes & ADJ_TIMECONST ) { /* p. 24 */
if ( txc - > constant < 0 ) { /* NTP v4 uses values > 6 */
result = - EINVAL ;
goto leave ;
}
2006-10-01 10:28:28 +04:00
time_constant = min ( txc - > constant + 4 , ( long ) MAXTC ) ;
2006-10-01 10:28:22 +04:00
}
if ( txc - > modes & ADJ_OFFSET ) { /* values checked earlier */
if ( txc - > modes = = ADJ_OFFSET_SINGLESHOT ) {
/* adjtime() is independent from ntp_adjtime() */
2006-10-01 10:28:25 +04:00
time_adjust = txc - > offset ;
2006-10-01 10:28:22 +04:00
}
else if ( time_status & STA_PLL ) {
2007-03-27 09:32:26 +04:00
time_offset = txc - > offset * NSEC_PER_USEC ;
2006-10-01 10:28:22 +04:00
/*
* Scale the phase adjustment and
* clamp to the operating range .
*/
2007-03-27 09:32:26 +04:00
time_offset = min ( time_offset , ( s64 ) MAXPHASE * NSEC_PER_USEC ) ;
time_offset = max ( time_offset , ( s64 ) - MAXPHASE * NSEC_PER_USEC ) ;
2006-10-01 10:28:22 +04:00
/*
* Select whether the frequency is to be controlled
* and in which mode ( PLL or FLL ) . Clamp to the operating
* range . Ugly multiply / divide should be replaced someday .
*/
if ( time_status & STA_FREQHOLD | | time_reftime = = 0 )
time_reftime = xtime . tv_sec ;
mtemp = xtime . tv_sec - time_reftime ;
time_reftime = xtime . tv_sec ;
2006-10-01 10:28:28 +04:00
2007-03-27 09:32:26 +04:00
freq_adj = time_offset * mtemp ;
2006-10-01 10:28:28 +04:00
freq_adj = shift_right ( freq_adj , time_constant * 2 +
( SHIFT_PLL + 2 ) * 2 - SHIFT_NSEC ) ;
if ( mtemp > = MINSEC & & ( time_status & STA_FLL | | mtemp > MAXSEC ) ) {
2007-03-27 09:32:26 +04:00
temp64 = time_offset < < ( SHIFT_NSEC - SHIFT_FLL ) ;
2006-10-01 10:28:28 +04:00
if ( time_offset < 0 ) {
temp64 = - temp64 ;
do_div ( temp64 , mtemp ) ;
freq_adj - = temp64 ;
} else {
do_div ( temp64 , mtemp ) ;
freq_adj + = temp64 ;
}
2006-10-01 10:28:22 +04:00
}
2006-10-01 10:28:27 +04:00
freq_adj + = time_freq ;
freq_adj = min ( freq_adj , ( s64 ) MAXFREQ_NSEC ) ;
time_freq = max ( freq_adj , ( s64 ) - MAXFREQ_NSEC ) ;
2007-03-27 09:32:26 +04:00
time_offset = div_long_long_rem_signed ( time_offset ,
NTP_INTERVAL_FREQ ,
& rem ) ;
time_offset < < = SHIFT_UPDATE ;
2006-10-01 10:28:22 +04:00
} /* STA_PLL */
} /* txc->modes & ADJ_OFFSET */
2006-10-01 10:28:22 +04:00
if ( txc - > modes & ADJ_TICK )
2006-10-01 10:28:22 +04:00
tick_usec = txc - > tick ;
2006-10-01 10:28:22 +04:00
2006-10-01 10:28:24 +04:00
if ( txc - > modes & ( ADJ_TICK | ADJ_FREQUENCY | ADJ_OFFSET ) )
2006-10-01 10:28:22 +04:00
ntp_update_frequency ( ) ;
2006-10-01 10:28:22 +04:00
} /* txc->modes */
leave : if ( ( time_status & ( STA_UNSYNC | STA_CLOCKERR ) ) ! = 0 )
result = TIME_ERROR ;
if ( ( txc - > modes & ADJ_OFFSET_SINGLESHOT ) = = ADJ_OFFSET_SINGLESHOT )
2007-03-27 09:32:26 +04:00
txc - > offset = save_adjust ;
2006-10-01 10:28:25 +04:00
else
2007-03-27 09:32:26 +04:00
txc - > offset = ( ( long ) shift_right ( time_offset , SHIFT_UPDATE ) ) *
NTP_INTERVAL_FREQ / 1000 ;
txc - > freq = ( time_freq / NSEC_PER_USEC ) < <
( SHIFT_USEC - SHIFT_NSEC ) ;
2006-10-01 10:28:22 +04:00
txc - > maxerror = time_maxerror ;
txc - > esterror = time_esterror ;
txc - > status = time_status ;
txc - > constant = time_constant ;
2006-10-01 10:28:29 +04:00
txc - > precision = 1 ;
2006-10-01 10:28:26 +04:00
txc - > tolerance = MAXFREQ ;
2006-10-01 10:28:22 +04:00
txc - > tick = tick_usec ;
/* PPS is not implemented, so these are zero */
txc - > ppsfreq = 0 ;
txc - > jitter = 0 ;
txc - > shift = 0 ;
txc - > stabil = 0 ;
txc - > jitcnt = 0 ;
txc - > calcnt = 0 ;
txc - > errcnt = 0 ;
txc - > stbcnt = 0 ;
write_sequnlock_irq ( & xtime_lock ) ;
do_gettimeofday ( & txc - > time ) ;
2007-07-21 15:37:37 +04:00
notify_cmos_timer ( ) ;
2006-10-01 10:28:22 +04:00
return ( result ) ;
}