diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2007-02-21 10:55:15 +0100 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2007-02-21 10:55:15 +0100 |
commit | 6c732de2d3673e28c6a976c98ee6ba4d197a919a (patch) | |
tree | 759b9e1d5a1a8ac33dee9ad5eb670ff99cb2d5ea /arch/s390 | |
parent | [S390] Optional ZONE_DMA for s390. (diff) | |
download | linux-6c732de2d3673e28c6a976c98ee6ba4d197a919a.tar.xz linux-6c732de2d3673e28c6a976c98ee6ba4d197a919a.zip |
[S390] etr: Add barrier() to etr_sync_cpu_start().
Force reading of *in_sync in while loop. Loops where the content that
is checked for is changed by a different cpu always should have some
sort of barrier() semantics.
Otherwise this might lead to very subtle bugs.
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/kernel/time.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index ee9fd7b85928..e1ad464b6f20 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -747,6 +747,7 @@ static void etr_adjust_time(unsigned long long clock, unsigned long long delay) } } +#ifdef CONFIG_SMP static void etr_sync_cpu_start(void *dummy) { int *in_sync = dummy; @@ -758,8 +759,14 @@ static void etr_sync_cpu_start(void *dummy) * __udelay will stop the cpu on an enabled wait psw until the * TOD is running again. */ - while (*in_sync == 0) + while (*in_sync == 0) { __udelay(1); + /* + * A different cpu changes *in_sync. Therefore use + * barrier() to force memory access. + */ + barrier(); + } if (*in_sync != 1) /* Didn't work. Clear per-cpu in sync bit again. */ etr_disable_sync_clock(NULL); @@ -773,6 +780,7 @@ static void etr_sync_cpu_start(void *dummy) static void etr_sync_cpu_end(void *dummy) { } +#endif /* CONFIG_SMP */ /* * Sync the TOD clock using the port refered to by aibp. This port |