diff options
Diffstat (limited to 'kernel/time.c')
| -rw-r--r-- | kernel/time.c | 70 | 
1 files changed, 37 insertions, 33 deletions
diff --git a/kernel/time.c b/kernel/time.c index ba9b338d183..7c7964c33ae 100644 --- a/kernel/time.c +++ b/kernel/time.c @@ -11,7 +11,7 @@   * Modification history kernel/time.c   *   * 1993-09-02    Philip Gladstone - *      Created file with time related functions from sched.c and adjtimex() + *      Created file with time related functions from sched/core.c and adjtimex()   * 1993-10-08    Torsten Duwe   *      adjtime interface update and CMOS clock write code   * 1995-08-13    Torsten Duwe @@ -27,10 +27,10 @@   *	with nanosecond accuracy   */ -#include <linux/module.h> +#include <linux/export.h>  #include <linux/timex.h>  #include <linux/capability.h> -#include <linux/clocksource.h> +#include <linux/timekeeper_internal.h>  #include <linux/errno.h>  #include <linux/syscalls.h>  #include <linux/security.h> @@ -115,6 +115,12 @@ SYSCALL_DEFINE2(gettimeofday, struct timeval __user *, tv,  }  /* + * Indicates if there is an offset between the system clock and the hardware + * clock/persistent clock/rtc. + */ +int persistent_clock_is_local; + +/*   * Adjust the time obtained from the CMOS to be UTC time instead of   * local time.   * @@ -132,11 +138,14 @@ SYSCALL_DEFINE2(gettimeofday, struct timeval __user *, tv,   */  static inline void warp_clock(void)  { -	struct timespec adjust; +	if (sys_tz.tz_minuteswest != 0) { +		struct timespec adjust; -	adjust = current_kernel_time(); -	adjust.tv_sec += sys_tz.tz_minuteswest * 60; -	do_settimeofday(&adjust); +		persistent_clock_is_local = 1; +		adjust.tv_sec = sys_tz.tz_minuteswest * 60; +		adjust.tv_nsec = 0; +		timekeeping_inject_offset(&adjust); +	}  }  /* @@ -150,7 +159,7 @@ static inline void warp_clock(void)   * various programs will get confused when the clock gets warped.   */ -int do_sys_settimeofday(struct timespec *tv, struct timezone *tz) +int do_sys_settimeofday(const struct timespec *tv, const struct timezone *tz)  {  	static int firsttime = 1;  	int error = 0; @@ -163,7 +172,6 @@ int do_sys_settimeofday(struct timespec *tv, 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 +181,7 @@ int do_sys_settimeofday(struct timespec *tv, 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;  } @@ -238,7 +241,7 @@ EXPORT_SYMBOL(current_fs_time);   * Avoid unnecessary multiplications/divisions in the   * two most common HZ cases:   */ -unsigned int inline jiffies_to_msecs(const unsigned long j) +unsigned int jiffies_to_msecs(const unsigned long j)  {  #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)  	return (MSEC_PER_SEC / HZ) * j; @@ -254,7 +257,7 @@ unsigned int inline jiffies_to_msecs(const unsigned long j)  }  EXPORT_SYMBOL(jiffies_to_msecs); -unsigned int inline jiffies_to_usecs(const unsigned long j) +unsigned int jiffies_to_usecs(const unsigned long j)  {  #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)  	return (USEC_PER_SEC / HZ) * j; @@ -575,7 +578,7 @@ EXPORT_SYMBOL(jiffies_to_timeval);  /*   * Convert jiffies/jiffies_64 to clock_t and back.   */ -clock_t jiffies_to_clock_t(long x) +clock_t jiffies_to_clock_t(unsigned long x)  {  #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0  # if HZ < USER_HZ @@ -645,7 +648,7 @@ u64 nsec_to_clock_t(u64 x)  }  /** - * nsecs_to_jiffies - Convert nsecs in u64 to jiffies + * nsecs_to_jiffies64 - Convert nsecs in u64 to jiffies64   *   * @n:	nsecs in u64   * @@ -657,7 +660,7 @@ u64 nsec_to_clock_t(u64 x)   *   NSEC_PER_SEC = 10^9 = (5^9 * 2^9) = (1953125 * 512)   *   ULLONG_MAX ns = 18446744073.709551615 secs = about 584 years   */ -unsigned long nsecs_to_jiffies(u64 n) +u64 nsecs_to_jiffies64(u64 n)  {  #if (NSEC_PER_SEC % HZ) == 0  	/* Common case, HZ = 100, 128, 200, 250, 256, 500, 512, 1000 etc. */ @@ -674,22 +677,23 @@ unsigned long nsecs_to_jiffies(u64 n)  #endif  } -#if (BITS_PER_LONG < 64) -u64 get_jiffies_64(void) +/** + * nsecs_to_jiffies - Convert nsecs in u64 to jiffies + * + * @n:	nsecs in u64 + * + * Unlike {m,u}secs_to_jiffies, type of input is not unsigned int but u64. + * And this doesn't return MAX_JIFFY_OFFSET since this function is designed + * for scheduler, not for use in device drivers to calculate timeout value. + * + * note: + *   NSEC_PER_SEC = 10^9 = (5^9 * 2^9) = (1953125 * 512) + *   ULLONG_MAX ns = 18446744073.709551615 secs = about 584 years + */ +unsigned long nsecs_to_jiffies(u64 n)  { -	unsigned long seq; -	u64 ret; - -	do { -		seq = read_seqbegin(&xtime_lock); -		ret = jiffies_64; -	} while (read_seqretry(&xtime_lock, seq)); -	return ret; +	return (unsigned long)nsecs_to_jiffies64(n);  } -EXPORT_SYMBOL(get_jiffies_64); -#endif - -EXPORT_SYMBOL(jiffies);  /*   * Add two timespec values and do a safety check for overflow.  | 
