[PATCH] s390: stop_hz_timer vs. xtime updates
authorMartin Schwidefsky <schwidefsky@de.ibm.com>
Mon, 7 Nov 2005 08:59:02 +0000 (00:59 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Mon, 7 Nov 2005 15:53:32 +0000 (07:53 -0800)
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>
arch/s390/kernel/time.c

index 9a1d958..c36353e 100644 (file)
@@ -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)) {