diff options
| author | George Anzinger <george@mvista.com> | 2005-07-29 00:16:16 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-07-29 00:46:05 -0400 |
| commit | 78fa74a23b16bdb0d944272b696915c4e0bb3ee1 (patch) | |
| tree | 5f0d83021afeb7adffce9b41557e1d2e3c8c08bd /kernel | |
| parent | a2d76bd8fa29f9b6dbf3ee8f6bc7bdda21bc5ce8 (diff) | |
[PATCH] posix timers: fix normalization problem
(We found this (after a customer complained) and it is in the kernel.org
kernel. Seems that for CLOCK_MONOTONIC absolute timers and clock_nanosleep
calls both the request time and wall_to_monotonic are subtracted prior to
the normalize resulting in an overflow in the existing normalize test.
This causes the result to be shifted ~4 seconds ahead instead of ~2 seconds
back in time.)
The normalize code in posix-timers.c fails when the tv_nsec member is ~1.2
seconds negative. This can happen on absolute timers (and
clock_nanosleeps) requested on CLOCK_MONOTONIC (both the request time and
wall_to_monotonic are subtracted resulting in the possibility of a number
close to -2 seconds.)
This fix uses the set_normalized_timespec() (which does not have an
overflow problem) to fix the problem and as a side effect makes the code
cleaner.
Signed-off-by: George Anzinger <george@mvista.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/posix-timers.c | 17 |
1 files changed, 3 insertions, 14 deletions
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index 5b7b4736d82b..10b2ad749d14 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c | |||
| @@ -896,21 +896,10 @@ static int adjust_abs_time(struct k_clock *clock, struct timespec *tp, | |||
| 896 | jiffies_64_f = get_jiffies_64(); | 896 | jiffies_64_f = get_jiffies_64(); |
| 897 | } | 897 | } |
| 898 | /* | 898 | /* |
| 899 | * Take away now to get delta | 899 | * Take away now to get delta and normalize |
| 900 | */ | 900 | */ |
| 901 | oc.tv_sec -= now.tv_sec; | 901 | set_normalized_timespec(&oc, oc.tv_sec - now.tv_sec, |
| 902 | oc.tv_nsec -= now.tv_nsec; | 902 | oc.tv_nsec - now.tv_nsec); |
| 903 | /* | ||
| 904 | * Normalize... | ||
| 905 | */ | ||
| 906 | while ((oc.tv_nsec - NSEC_PER_SEC) >= 0) { | ||
| 907 | oc.tv_nsec -= NSEC_PER_SEC; | ||
| 908 | oc.tv_sec++; | ||
| 909 | } | ||
| 910 | while ((oc.tv_nsec) < 0) { | ||
| 911 | oc.tv_nsec += NSEC_PER_SEC; | ||
| 912 | oc.tv_sec--; | ||
| 913 | } | ||
| 914 | }else{ | 903 | }else{ |
| 915 | jiffies_64_f = get_jiffies_64(); | 904 | jiffies_64_f = get_jiffies_64(); |
| 916 | } | 905 | } |
