parisc: Find a new timesync master if current CPU is removed
authorHelge Deller <deller@gmx.de>
Sun, 27 Mar 2022 13:03:53 +0000 (15:03 +0200)
committerHelge Deller <deller@gmx.de>
Tue, 29 Mar 2022 19:37:13 +0000 (21:37 +0200)
When CPU hotplugging is enabled, the user may want to remove the
current CPU which is providing the timer ticks. If this happens
we need to find a new timesync master.

Signed-off-by: Helge Deller <deller@gmx.de>
arch/parisc/include/asm/processor.h
arch/parisc/kernel/smp.c
arch/parisc/kernel/time.c

index 0063642..4621ceb 100644 (file)
@@ -95,6 +95,7 @@ struct cpuinfo_parisc {
 
 extern struct system_cpuinfo_parisc boot_cpu_data;
 DECLARE_PER_CPU(struct cpuinfo_parisc, cpu_data);
+extern int time_keeper_id;             /* CPU used for timekeeping */
 
 #define CPU_HVERSION ((boot_cpu_data.hversion >> 4) & 0x0FFF)
 
index 8c5ea45..24d0744 100644 (file)
@@ -465,6 +465,12 @@ int __cpu_disable(void)
         */
        set_cpu_online(cpu, false);
 
+       /* Find a new timesync master */
+       if (cpu == time_keeper_id) {
+               time_keeper_id = cpumask_first(cpu_online_mask);
+               pr_info("CPU %d is now promoted to time-keeper master\n", time_keeper_id);
+       }
+
        disable_percpu_irq(IPI_IRQ);
 
        irq_migrate_all_off_this_cpu();
index 874b128..bb27dfe 100644 (file)
@@ -40,6 +40,8 @@
 
 #include <linux/timex.h>
 
+int time_keeper_id __read_mostly;      /* CPU used for timekeeping. */
+
 static unsigned long clocktick __ro_after_init;        /* timer cycles per tick */
 
 /*
@@ -84,7 +86,7 @@ irqreturn_t __irq_entry timer_interrupt(int irq, void *dev_id)
        cpuinfo->it_value = next_tick;
 
        /* Go do system house keeping. */
-       if (cpu != 0)
+       if (IS_ENABLED(CONFIG_SMP) && (cpu != time_keeper_id))
                ticks_elapsed = 0;
        legacy_timer_tick(ticks_elapsed);