| From afdb4a5b1d340e4afffc65daa21cc71890d7d589 Mon Sep 17 00:00:00 2001 |
| From: Helge Deller <deller@gmx.de> |
| Date: Sat, 4 Dec 2021 21:21:46 +0100 |
| Subject: parisc: Mark cr16 CPU clocksource unstable on all SMP machines |
| |
| From: Helge Deller <deller@gmx.de> |
| |
| commit afdb4a5b1d340e4afffc65daa21cc71890d7d589 upstream. |
| |
| In commit c8c3735997a3 ("parisc: Enhance detection of synchronous cr16 |
| clocksources") I assumed that CPUs on the same physical core are syncronous. |
| While booting up the kernel on two different C8000 machines, one with a |
| dual-core PA8800 and one with a dual-core PA8900 CPU, this turned out to be |
| wrong. The symptom was that I saw a jump in the internal clocks printed to the |
| syslog and strange overall behaviour. On machines which have 4 cores (2 |
| dual-cores) the problem isn't visible, because the current logic already marked |
| the cr16 clocksource unstable in this case. |
| |
| This patch now marks the cr16 interval timers unstable if we have more than one |
| CPU in the system, and it fixes this issue. |
| |
| Fixes: c8c3735997a3 ("parisc: Enhance detection of synchronous cr16 clocksources") |
| Signed-off-by: Helge Deller <deller@gmx.de> |
| Cc: <stable@vger.kernel.org> # v5.15+ |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/parisc/kernel/time.c | 24 +++++------------------- |
| 1 file changed, 5 insertions(+), 19 deletions(-) |
| |
| --- a/arch/parisc/kernel/time.c |
| +++ b/arch/parisc/kernel/time.c |
| @@ -252,27 +252,13 @@ void __init time_init(void) |
| static int __init init_cr16_clocksource(void) |
| { |
| /* |
| - * The cr16 interval timers are not syncronized across CPUs on |
| - * different sockets, so mark them unstable and lower rating on |
| - * multi-socket SMP systems. |
| + * The cr16 interval timers are not syncronized across CPUs, even if |
| + * they share the same socket. |
| */ |
| if (num_online_cpus() > 1 && !running_on_qemu) { |
| - int cpu; |
| - unsigned long cpu0_loc; |
| - cpu0_loc = per_cpu(cpu_data, 0).cpu_loc; |
| - |
| - for_each_online_cpu(cpu) { |
| - if (cpu == 0) |
| - continue; |
| - if ((cpu0_loc != 0) && |
| - (cpu0_loc == per_cpu(cpu_data, cpu).cpu_loc)) |
| - continue; |
| - |
| - clocksource_cr16.name = "cr16_unstable"; |
| - clocksource_cr16.flags = CLOCK_SOURCE_UNSTABLE; |
| - clocksource_cr16.rating = 0; |
| - break; |
| - } |
| + clocksource_cr16.name = "cr16_unstable"; |
| + clocksource_cr16.flags = CLOCK_SOURCE_UNSTABLE; |
| + clocksource_cr16.rating = 0; |
| } |
| |
| /* XXX: We may want to mark sched_clock stable here if cr16 clocks are |