diff options
| author | Andrew Morton <akpm@digeo.com> | 2003-06-14 07:19:27 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2003-06-14 07:19:27 -0700 |
| commit | b9cebc5d5f51e520f9e1772976fff56244ded862 (patch) | |
| tree | 5f922a7652de1f95b9554087ea1e8ca31d908407 /kernel/time.c | |
| parent | 90ea34be80a2e3c0bf2970c8666180e50fc57d0a (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.c | 24 |
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); |
