diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2005-11-07 03:59:02 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-07 10:53:32 -0500 |
commit | 1b44e98d7d0754bbcf0222baf179f5e2e3dbea7b (patch) | |
tree | c4e69506205a175fa9675e5dcec1ad4944c4b87a /arch/s390/kernel/time.c | |
parent | e1c3ad96f662bf1071a71feffadfe0f7604f14e2 (diff) |
[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/s390/kernel/time.c')
-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; | |||
237 | */ | 237 | */ |
238 | static inline void stop_hz_timer(void) | 238 | static inline void stop_hz_timer(void) |
239 | { | 239 | { |
240 | unsigned long flags; | ||
241 | unsigned long seq, next; | ||
240 | __u64 timer, todval; | 242 | __u64 timer, todval; |
241 | 243 | ||
242 | if (sysctl_hz_timer != 0) | 244 | if (sysctl_hz_timer != 0) |
@@ -257,7 +259,11 @@ static inline void stop_hz_timer(void) | |||
257 | * This cpu is going really idle. Set up the clock comparator | 259 | * This cpu is going really idle. Set up the clock comparator |
258 | * for the next event. | 260 | * for the next event. |
259 | */ | 261 | */ |
260 | timer = (__u64) (next_timer_interrupt() - jiffies) + jiffies_64; | 262 | next = next_timer_interrupt(); |
263 | do { | ||
264 | seq = read_seqbegin_irqsave(&xtime_lock, flags); | ||
265 | timer = (__u64)(next - jiffies) + jiffies_64; | ||
266 | } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); | ||
261 | todval = -1ULL; | 267 | todval = -1ULL; |
262 | /* Be careful about overflows. */ | 268 | /* Be careful about overflows. */ |
263 | if (timer < (-1ULL / CLK_TICKS_PER_JIFFY)) { | 269 | if (timer < (-1ULL / CLK_TICKS_PER_JIFFY)) { |