diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2005-11-07 00:59:02 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-07 07:53:32 -0800 |
commit | 1b44e98d7d0754bbcf0222baf179f5e2e3dbea7b (patch) | |
tree | c4e69506205a175fa9675e5dcec1ad4944c4b87a /arch | |
parent | e1c3ad96f662bf1071a71feffadfe0f7604f14e2 (diff) | |
download | linux-1b44e98d7d0754bbcf0222baf179f5e2e3dbea7b.tar.bz2 |
[PATCH] s390: stop_hz_timer vs. xtime updates
The calculation of the value return by next_timer_interrupt from jiffies to
jiffies_64 is racy against xtime updates. We need to protect the calculation
with read_seqbegin/read_seqretry.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/s390/kernel/time.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 9a1d95894f3d..c36353e8c140 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -237,6 +237,8 @@ int sysctl_hz_timer = 1; */ static inline void stop_hz_timer(void) { + unsigned long flags; + unsigned long seq, next; __u64 timer, todval; if (sysctl_hz_timer != 0) @@ -257,7 +259,11 @@ static inline void stop_hz_timer(void) * This cpu is going really idle. Set up the clock comparator * for the next event. */ - timer = (__u64) (next_timer_interrupt() - jiffies) + jiffies_64; + next = next_timer_interrupt(); + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); + timer = (__u64)(next - jiffies) + jiffies_64; + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); todval = -1ULL; /* Be careful about overflows. */ if (timer < (-1ULL / CLK_TICKS_PER_JIFFY)) { |