diff options
-rw-r--r-- | arch/parisc/include/asm/processor.h | 1 | ||||
-rw-r--r-- | arch/parisc/kernel/smp.c | 6 | ||||
-rw-r--r-- | arch/parisc/kernel/time.c | 4 |
3 files changed, 10 insertions, 1 deletions
diff --git a/arch/parisc/include/asm/processor.h b/arch/parisc/include/asm/processor.h index 006364212795..4621ceb51314 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 8c5ea457b6e1..24d0744c3b3a 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 874b128c5783..bb27dfeeddfc 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c @@ -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); |