summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2013-10-28 12:15:32 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-11-29 11:11:53 -0800
commitd4f2a840c79ca283a453b9cd6329ccb530cb0f70 (patch)
tree0f52787f2afc6938c7b7c89828b3de4cb2650e93 /arch
parentf3170c7a91c9520eeb6d2c13d0897172ebd6c228 (diff)
downloadlinux-3.10-d4f2a840c79ca283a453b9cd6329ccb530cb0f70.tar.gz
linux-3.10-d4f2a840c79ca283a453b9cd6329ccb530cb0f70.tar.bz2
linux-3.10-d4f2a840c79ca283a453b9cd6329ccb530cb0f70.zip
s390/vtime: correct idle time calculation
commit 4560e7c3317c7a2b370e36dadd3a3bac2ed70818 upstream. 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. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/s390/kernel/smp.c4
-rw-r--r--arch/s390/kernel/vtime.c2
2 files changed, 3 insertions, 3 deletions
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 4f977d0d25c..14647fe09d0 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -933,7 +933,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);
@@ -951,7 +951,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);
}
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index 3fb09359eda..737d50caa4f 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -190,7 +190,7 @@ cputime64_t s390_get_idle_time(int cpu)
sequence = ACCESS_ONCE(idle->sequence);
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));
return idle_enter ? ((idle_exit ?: now) - idle_enter) : 0;
}