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 | |
parent | 118bcd31b309d12638f67729d5d96d4974750249 (diff) | |
download | op-kernel-dev-6c732de2d3673e28c6a976c98ee6ba4d197a919a.zip op-kernel-dev-6c732de2d3673e28c6a976c98ee6ba4d197a919a.tar.gz |
[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>
-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 ee9fd7b..e1ad464 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 |