From 1afde47d082c92c4fd3d9b322d944f8d87469834 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Sun, 27 Mar 2022 15:03:53 +0200 Subject: [PATCH] parisc: Find a new timesync master if current CPU is removed 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 --- arch/parisc/include/asm/processor.h | 1 + arch/parisc/kernel/smp.c | 6 ++++++ arch/parisc/kernel/time.c | 4 +++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/arch/parisc/include/asm/processor.h b/arch/parisc/include/asm/processor.h index 0063642127954..4621ceb513147 100644 --- a/arch/parisc/include/asm/processor.h +++ b/arch/parisc/include/asm/processor.h @@ -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) diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c index 8c5ea457b6e12..24d0744c3b3ab 100644 --- a/arch/parisc/kernel/smp.c +++ b/arch/parisc/kernel/smp.c @@ -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(); diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index 874b128c5783b..bb27dfeeddfcc 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c @@ -40,6 +40,8 @@ #include +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); -- 2.30.2