summaryrefslogtreecommitdiff
path: root/kernel/time.c
diff options
context:
space:
mode:
authorAndrew Morton <akpm@digeo.com>2003-06-14 07:19:27 -0700
committerLinus Torvalds <torvalds@home.transmeta.com>2003-06-14 07:19:27 -0700
commitb9cebc5d5f51e520f9e1772976fff56244ded862 (patch)
tree5f922a7652de1f95b9554087ea1e8ca31d908407 /kernel/time.c
parent90ea34be80a2e3c0bf2970c8666180e50fc57d0a (diff)
[PATCH] Some clean up of the time code.
From: george anzinger <george@mvista.com> This patch does the following: Pushs down the change from timeval to timespec in the settime routines. Fixes two places where time was set without updating the monotonic clock offset. (Changes sys_stime() to call do_settimeofday() and changes clock_warp to do the update directly.) These were bugs! Changes the uptime code to use the posix_clock_monotonic notion of uptime instead of the jiffies. This time will track NTP changes and so should be better than your standard wristwatch (if your using ntp). Changes posix_clock_monotonic to start at 0 on boot (was set to start at initial jiffies). Fixes a bug (never experienced) in timer_create() in posix-timers.c where we "could" have released timer_id 0 if "id resources" were low. Adds a test in do_settimeofday() to error out (EINVAL) attempts to use unnormalized times. This is passed back up to both settimeofday and posix_setclock(). Warning: Requires changes in .../arch/???/kernel/time.c to change do_settimeofday() to return an error if time is not normalized and to use a timespec instead of timeval for its input.
Diffstat (limited to 'kernel/time.c')
-rw-r--r--kernel/time.c24
1 files changed, 10 insertions, 14 deletions
diff --git a/kernel/time.c b/kernel/time.c
index 37b0415545ff..36febc007a93 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -68,22 +68,15 @@ asmlinkage long sys_time(int * tloc)
asmlinkage long sys_stime(int * tptr)
{
- int value;
+ struct timespec tv;
if (!capable(CAP_SYS_TIME))
return -EPERM;
- if (get_user(value, tptr))
+ if (get_user(tv.tv_sec, tptr))
return -EFAULT;
- write_seqlock_irq(&xtime_lock);
- time_interpolator_reset();
- xtime.tv_sec = value;
- xtime.tv_nsec = 0;
- time_adjust = 0; /* stop active adjtime() */
- time_status |= STA_UNSYNC;
- time_maxerror = NTP_PHASE_LIMIT;
- time_esterror = NTP_PHASE_LIMIT;
- write_sequnlock_irq(&xtime_lock);
+ tv.tv_nsec = 0;
+ do_settimeofday(&tv);
return 0;
}
@@ -123,9 +116,11 @@ asmlinkage long sys_gettimeofday(struct timeval __user *tv, struct timezone __us
inline static void warp_clock(void)
{
write_seqlock_irq(&xtime_lock);
+ wall_to_monotonic.tv_sec -= sys_tz.tz_minuteswest * 60;
xtime.tv_sec += sys_tz.tz_minuteswest * 60;
time_interpolator_update(sys_tz.tz_minuteswest * 60 * NSEC_PER_SEC);
write_sequnlock_irq(&xtime_lock);
+ clock_was_set();
}
/*
@@ -139,7 +134,7 @@ inline static void warp_clock(void)
* various programs will get confused when the clock gets warped.
*/
-int do_sys_settimeofday(struct timeval *tv, struct timezone *tz)
+int do_sys_settimeofday(struct timespec *tv, struct timezone *tz)
{
static int firsttime = 1;
@@ -160,14 +155,14 @@ int do_sys_settimeofday(struct timeval *tv, struct timezone *tz)
/* SMP safe, again the code in arch/foo/time.c should
* globally block out interrupts when it runs.
*/
- do_settimeofday(tv);
+ return do_settimeofday(tv);
}
return 0;
}
asmlinkage long sys_settimeofday(struct timeval __user *tv, struct timezone __user *tz)
{
- struct timeval new_tv;
+ struct timespec new_tv;
struct timezone new_tz;
if (tv) {
@@ -177,6 +172,7 @@ asmlinkage long sys_settimeofday(struct timeval __user *tv, struct timezone __us
if (tz) {
if (copy_from_user(&new_tz, tz, sizeof(*tz)))
return -EFAULT;
+ new_tv.tv_nsec *= NSEC_PER_USEC;
}
return do_sys_settimeofday(tv ? &new_tv : NULL, tz ? &new_tz : NULL);