Message ID | 20210307022446.63732-2-guoren@kernel.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [1/2] csky: Enable generic clockevent broadcast | expand |
On Sun, Mar 7, 2021 at 7:55 AM <guoren@kernel.org> wrote: > > From: Guo Ren <guoren@linux.alibaba.com> > > When percpu-timers are stopped by deep power saving mode, we > need system timer help to broadcast IPI_TIMER. > > This is first introduced by broken x86 hardware, where the local apic > timer stops in C3 state. But many other architectures(powerpc, mips, > arm, hexagon, openrisc, sh) have supported the infrastructure to > deal with Power Management issues. > > Signed-off-by: Guo Ren <guoren@linux.alibaba.com> > Cc: Arnd Bergmann <arnd@arndb.de> > Cc: Thomas Gleixner <tglx@linutronix.de> > Cc: Daniel Lezcano <daniel.lezcano@linaro.org> > Cc: Anup Patel <anup.patel@wdc.com> > Cc: Atish Patra <atish.patra@wdc.com> > Cc: Palmer Dabbelt <palmerdabbelt@google.com> > Cc: Greentime Hu <greentime.hu@sifive.com> Looks good to me. Reviewed-by: Anup Patel <anup@brainfault.org> Regards, Anup > --- > arch/riscv/Kconfig | 2 ++ > arch/riscv/kernel/smp.c | 16 ++++++++++++++++ > 2 files changed, 18 insertions(+) > > diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig > index 85d626b8ce5e..8637e7344abe 100644 > --- a/arch/riscv/Kconfig > +++ b/arch/riscv/Kconfig > @@ -28,6 +28,7 @@ config RISCV > select ARCH_HAS_SET_DIRECT_MAP > select ARCH_HAS_SET_MEMORY > select ARCH_HAS_STRICT_KERNEL_RWX if MMU > + select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST > select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX > select ARCH_OPTIONAL_KERNEL_RWX_DEFAULT > select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU > @@ -39,6 +40,7 @@ config RISCV > select EDAC_SUPPORT > select GENERIC_ARCH_TOPOLOGY if SMP > select GENERIC_ATOMIC64 if !64BIT > + select GENERIC_CLOCKEVENTS_BROADCAST if SMP > select GENERIC_EARLY_IOREMAP > select GENERIC_GETTIMEOFDAY if HAVE_GENERIC_VDSO > select GENERIC_IOREMAP > diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c > index ea028d9e0d24..8325d33411d8 100644 > --- a/arch/riscv/kernel/smp.c > +++ b/arch/riscv/kernel/smp.c > @@ -9,6 +9,7 @@ > */ > > #include <linux/cpu.h> > +#include <linux/clockchips.h> > #include <linux/interrupt.h> > #include <linux/module.h> > #include <linux/profile.h> > @@ -27,6 +28,7 @@ enum ipi_message_type { > IPI_CALL_FUNC, > IPI_CPU_STOP, > IPI_IRQ_WORK, > + IPI_TIMER, > IPI_MAX > }; > > @@ -176,6 +178,12 @@ void handle_IPI(struct pt_regs *regs) > irq_work_run(); > } > > +#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST > + if (ops & (1 << IPI_TIMER)) { > + stats[IPI_TIMER]++; > + tick_receive_broadcast(); > + } > +#endif > BUG_ON((ops >> IPI_MAX) != 0); > > /* Order data access and bit testing. */ > @@ -192,6 +200,7 @@ static const char * const ipi_names[] = { > [IPI_CALL_FUNC] = "Function call interrupts", > [IPI_CPU_STOP] = "CPU stop interrupts", > [IPI_IRQ_WORK] = "IRQ work interrupts", > + [IPI_TIMER] = "Timer broadcast interrupts", > }; > > void show_ipi_stats(struct seq_file *p, int prec) > @@ -217,6 +226,13 @@ void arch_send_call_function_single_ipi(int cpu) > send_ipi_single(cpu, IPI_CALL_FUNC); > } > > +#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST > +void tick_broadcast(const struct cpumask *mask) > +{ > + send_ipi_mask(mask, IPI_TIMER); > +} > +#endif > + > void smp_send_stop(void) > { > unsigned long timeout; > -- > 2.25.1 > > > _______________________________________________ > linux-riscv mailing list > linux-riscv@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-riscv
On Sat, 06 Mar 2021 18:24:46 PST (-0800), guoren@kernel.org wrote: > From: Guo Ren <guoren@linux.alibaba.com> > > When percpu-timers are stopped by deep power saving mode, we > need system timer help to broadcast IPI_TIMER. > > This is first introduced by broken x86 hardware, where the local apic > timer stops in C3 state. But many other architectures(powerpc, mips, > arm, hexagon, openrisc, sh) have supported the infrastructure to > deal with Power Management issues. > > Signed-off-by: Guo Ren <guoren@linux.alibaba.com> > Cc: Arnd Bergmann <arnd@arndb.de> > Cc: Thomas Gleixner <tglx@linutronix.de> > Cc: Daniel Lezcano <daniel.lezcano@linaro.org> > Cc: Anup Patel <anup.patel@wdc.com> > Cc: Atish Patra <atish.patra@wdc.com> > Cc: Palmer Dabbelt <palmerdabbelt@google.com> > Cc: Greentime Hu <greentime.hu@sifive.com> > --- > arch/riscv/Kconfig | 2 ++ > arch/riscv/kernel/smp.c | 16 ++++++++++++++++ > 2 files changed, 18 insertions(+) > > diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig > index 85d626b8ce5e..8637e7344abe 100644 > --- a/arch/riscv/Kconfig > +++ b/arch/riscv/Kconfig > @@ -28,6 +28,7 @@ config RISCV > select ARCH_HAS_SET_DIRECT_MAP > select ARCH_HAS_SET_MEMORY > select ARCH_HAS_STRICT_KERNEL_RWX if MMU > + select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST > select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX > select ARCH_OPTIONAL_KERNEL_RWX_DEFAULT > select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU > @@ -39,6 +40,7 @@ config RISCV > select EDAC_SUPPORT > select GENERIC_ARCH_TOPOLOGY if SMP > select GENERIC_ATOMIC64 if !64BIT > + select GENERIC_CLOCKEVENTS_BROADCAST if SMP > select GENERIC_EARLY_IOREMAP > select GENERIC_GETTIMEOFDAY if HAVE_GENERIC_VDSO > select GENERIC_IOREMAP > diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c > index ea028d9e0d24..8325d33411d8 100644 > --- a/arch/riscv/kernel/smp.c > +++ b/arch/riscv/kernel/smp.c > @@ -9,6 +9,7 @@ > */ > > #include <linux/cpu.h> > +#include <linux/clockchips.h> > #include <linux/interrupt.h> > #include <linux/module.h> > #include <linux/profile.h> > @@ -27,6 +28,7 @@ enum ipi_message_type { > IPI_CALL_FUNC, > IPI_CPU_STOP, > IPI_IRQ_WORK, > + IPI_TIMER, > IPI_MAX > }; > > @@ -176,6 +178,12 @@ void handle_IPI(struct pt_regs *regs) > irq_work_run(); > } > > +#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST > + if (ops & (1 << IPI_TIMER)) { > + stats[IPI_TIMER]++; > + tick_receive_broadcast(); > + } > +#endif > BUG_ON((ops >> IPI_MAX) != 0); > > /* Order data access and bit testing. */ > @@ -192,6 +200,7 @@ static const char * const ipi_names[] = { > [IPI_CALL_FUNC] = "Function call interrupts", > [IPI_CPU_STOP] = "CPU stop interrupts", > [IPI_IRQ_WORK] = "IRQ work interrupts", > + [IPI_TIMER] = "Timer broadcast interrupts", > }; > > void show_ipi_stats(struct seq_file *p, int prec) > @@ -217,6 +226,13 @@ void arch_send_call_function_single_ipi(int cpu) > send_ipi_single(cpu, IPI_CALL_FUNC); > } > > +#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST > +void tick_broadcast(const struct cpumask *mask) > +{ > + send_ipi_mask(mask, IPI_TIMER); > +} > +#endif > + > void smp_send_stop(void) > { > unsigned long timeout; Thanks, this is on for-next.
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 85d626b8ce5e..8637e7344abe 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -28,6 +28,7 @@ config RISCV select ARCH_HAS_SET_DIRECT_MAP select ARCH_HAS_SET_MEMORY select ARCH_HAS_STRICT_KERNEL_RWX if MMU + select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX select ARCH_OPTIONAL_KERNEL_RWX_DEFAULT select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU @@ -39,6 +40,7 @@ config RISCV select EDAC_SUPPORT select GENERIC_ARCH_TOPOLOGY if SMP select GENERIC_ATOMIC64 if !64BIT + select GENERIC_CLOCKEVENTS_BROADCAST if SMP select GENERIC_EARLY_IOREMAP select GENERIC_GETTIMEOFDAY if HAVE_GENERIC_VDSO select GENERIC_IOREMAP diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c index ea028d9e0d24..8325d33411d8 100644 --- a/arch/riscv/kernel/smp.c +++ b/arch/riscv/kernel/smp.c @@ -9,6 +9,7 @@ */ #include <linux/cpu.h> +#include <linux/clockchips.h> #include <linux/interrupt.h> #include <linux/module.h> #include <linux/profile.h> @@ -27,6 +28,7 @@ enum ipi_message_type { IPI_CALL_FUNC, IPI_CPU_STOP, IPI_IRQ_WORK, + IPI_TIMER, IPI_MAX }; @@ -176,6 +178,12 @@ void handle_IPI(struct pt_regs *regs) irq_work_run(); } +#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST + if (ops & (1 << IPI_TIMER)) { + stats[IPI_TIMER]++; + tick_receive_broadcast(); + } +#endif BUG_ON((ops >> IPI_MAX) != 0); /* Order data access and bit testing. */ @@ -192,6 +200,7 @@ static const char * const ipi_names[] = { [IPI_CALL_FUNC] = "Function call interrupts", [IPI_CPU_STOP] = "CPU stop interrupts", [IPI_IRQ_WORK] = "IRQ work interrupts", + [IPI_TIMER] = "Timer broadcast interrupts", }; void show_ipi_stats(struct seq_file *p, int prec) @@ -217,6 +226,13 @@ void arch_send_call_function_single_ipi(int cpu) send_ipi_single(cpu, IPI_CALL_FUNC); } +#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST +void tick_broadcast(const struct cpumask *mask) +{ + send_ipi_mask(mask, IPI_TIMER); +} +#endif + void smp_send_stop(void) { unsigned long timeout;