summaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/smp.c
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2013-10-28 12:15:32 +0100
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2013-10-31 09:52:52 +0100
commit4560e7c3317c7a2b370e36dadd3a3bac2ed70818 (patch)
treeb0fd4d8705f388783dd893a472105013b702991d /arch/s390/kernel/smp.c
parent7ab64a85e1a009046f97413a573e83fd85f7804d (diff)
s390/vtime: correct idle time calculation
Use the ACCESS_ONCE macro for both accesses to idle->sequence in the loops to calculate the idle time. If only one access uses the macro, the compiler is free to cache the value for the second access which can cause endless loops. Cc: stable@vger.kernel.org # 3.6+ Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/smp.c')
-rw-r--r--arch/s390/kernel/smp.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 739313db71e..dc4a5346506 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -920,7 +920,7 @@ static ssize_t show_idle_count(struct device *dev,
idle_count = ACCESS_ONCE(idle->idle_count);
if (ACCESS_ONCE(idle->clock_idle_enter))
idle_count++;
- } while ((sequence & 1) || (idle->sequence != sequence));
+ } while ((sequence & 1) || (ACCESS_ONCE(idle->sequence) != sequence));
return sprintf(buf, "%llu\n", idle_count);
}
static DEVICE_ATTR(idle_count, 0444, show_idle_count, NULL);
@@ -938,7 +938,7 @@ static ssize_t show_idle_time(struct device *dev,
idle_time = ACCESS_ONCE(idle->idle_time);
idle_enter = ACCESS_ONCE(idle->clock_idle_enter);
idle_exit = ACCESS_ONCE(idle->clock_idle_exit);
- } while ((sequence & 1) || (idle->sequence != sequence));
+ } while ((sequence & 1) || (ACCESS_ONCE(idle->sequence) != sequence));
idle_time += idle_enter ? ((idle_exit ? : now) - idle_enter) : 0;
return sprintf(buf, "%llu\n", idle_time >> 12);
}