From: Heiko Carstens Date: Wed, 21 Feb 2007 09:55:15 +0000 (+0100) Subject: [S390] etr: Add barrier() to etr_sync_cpu_start(). X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=6c732de2d3673e28c6a976c98ee6ba4d197a919a;p=linux-beck.git [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 Signed-off-by: Martin Schwidefsky --- 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