Consolidating GIC per-cpu interrupts
Subsystems (8)
v2 cover Consolidating GIC per-cpu interrupts
The current GIC per-cpu interrupt (aka PPIs) suffers from a number of problems:
- It uses a completely separate scheme to handle the interrupts, mostly because the PPI concept doesn't really match the kernel view of an interrupt.
- Some low-level code gets duplicated, as usual...
- At least one platform (msm) has started implementing its own alternative scheme.
The proposed solution is to let the GIC code expose the PPIs as something that the kernel can manage. Instead of having a single interrupt number shared on all cores, make the interrupt number be different on each CPU.
This enables the use of the normal kernel API (request_irq() and friends) and the elimination of some low level code.
This patch set is based on 2.6.39-rc6, and depends on Will Deacon's GIC fasteoi patches. Tested on VExpress, PB-11MP, Pandaboard and SMDK-S5PV310.
RFC PATCH v2 1/12 ARM: gic: add per-cpu interrupt multiplexer
The kernel doesn't handle very well the concept of per-cpu interrupt as implemented by the ARM architecture (the same interrupt level is exposed on each core).
To work around the problem, add another irq_chip to handle PPIs and remap them so that a single interrupt number is only used on a given CPU (for example, IRQ 29 and 30 get exposed as IRQ 128 and 129 on core 0, 130 and 131 on core 1...).
A helper function gic_ppi_to_vppi() is used to convert the PPI number to the per-processor IRQ.
--- arch/arm/common/Kconfig | 5 + arch/arm/common/gic.c | 133 ++++++++++++++++++++++- arch/arm/include/asm/entry-macro-multi.S | 2 +- arch/arm/include/asm/hardware/entry-macro-gic.S | 19 ++-- arch/arm/include/asm/hardware/gic.h | 11 ++ arch/arm/kernel/irq.c | 8 ++- 6 files changed, 165 insertions(+), 13 deletions(-)
arch/arm/common/Kconfig +5 -0
@@ -1,6 +1,11 @@ config ARM_GIC bool +config ARM_GIC_VPPI + depends on ARM_GIC + select SPARSE_IRQ + bool + config ARM_VIC bool
arch/arm/common/gic.c +129 -4
168 lines not on this page · raw message
arch/arm/include/asm/entry-macro-multi.S +1 -1
@@ -24,7 +24,7 @@ adrne lr, BSYM(1b) bne do_IPI -#ifdef CONFIG_LOCAL_TIMERS +#if defined(CONFIG_LOCAL_TIMERS) && !defined(CONFIG_ARM_GIC_VPPI) test_for_ltirq r0, r6, r5, lr movne r0, sp adrne lr, BSYM(1b)
arch/arm/include/asm/hardware/entry-macro-gic.S +12 -7
@@ -17,23 +17,26 @@ .endm #endif +#ifdef CONFIG_ARM_GIC_VPPI +#define DO_IRQ_BASE 16 +#else +#define DO_IRQ_BASE 30 +#endif + /* * The interrupt numbering scheme is defined in the * interrupt controller spec. To wit: * * Interrupts 0-15 are IPI - * 16-28 are reserved - * 29-31 are local. We allow 30 to be used for the watchdog. + * 16-31 are local. We allow 30 to be used for the watchdog. * 32-1020 are global * 1021-1022 are reserved * 1023 is "spurious" (no interrupt) * - * For now, we ignore all local interrupts so only return an interrupt if it's - * between 30 and 1020. The test_for_ipi routine below will pick up on IPIs. - * * A simple read from the controller will tell us the number of the highest * priority enabled interrupt. We then just need to check whether it is in the - * valid range for an IRQ (30-1020 inclusive). + * valid range for an IRQ (30-1020 inclusive). If CONFIG_ARM_GIC_VPPI is + * enabled, local interrupts are handled the same way as global ones. */ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
@@ -43,7 +46,7 @@ ldr \tmp, =1021 bic \irqnr, \irqstat, #0x1c00 - cmp \irqnr, #29 + cmp \irqnr, #(DO_IRQ_BASE - 1) cmpcc \irqnr, \irqnr cmpne \irqnr, \tmp cmpcs \irqnr, \irqnr
@@ -63,6 +66,7 @@ cmpcs \irqnr, \irqnr .endm +#ifndef CONFIG_ARM_GIC_VPPI /* As above, this assumes that irqstat and base are preserved.. */ .macro test_for_ltirq, irqnr, irqstat, base, tmp
@@ -73,3 +77,4 @@ streq \irqstat, [\base, #GIC_CPU_EOI] cmp \tmp, #0 .endm +#endif
arch/arm/include/asm/hardware/gic.h +11 -0
@@ -33,6 +33,8 @@#define GIC_DIST_SOFTINT 0xf00#ifndef __ASSEMBLY__ +#include <linux/cpumask.h> +extern void __iomem *gic_cpu_base_addr;extern struct irq_chip gic_arch_extn;
@@ -41,6 +43,15 @@ void gic_secondary_init(unsigned int);void gic_cascade_irq (unsigned int gic_nr,unsigned int irq);void gic_raise_softirq (const struct cpumask *mask,unsigned int irq);void gic_enable_ppi (unsigned int ); +#ifdef CONFIG_ARM_GIC_VPPI +unsigned int gic_ppi_to_vppi (unsigned int irq); +#else +static inline unsigned int gic_ppi_to_vppi (unsigned int irq) +{ +return irq; +} +#endif +#endif #endif
arch/arm/kernel/irq.c +7 -1
@@ -124,8 +124,14 @@ void __init init_IRQ(void)#ifdef CONFIG_SPARSE_IRQ int __init arch_probe_nr_irqs (void ) { +int initcnt; + nr_irqs = machine_desc->nr_irqs ? machine_desc->nr_irqs :NR_IRQS ; -return nr_irqs; + initcnt = nr_irqs; +#ifdef CONFIG_ARM_GIC_VPPI + nr_irqs +=16 *8 ;/* 16 PPIs, 8 CPUs */ +#endif +return initcnt; }#endif
Signature · 1 line
1.7.0.4
RFC PATCH v2 2/12 ARM: smp_twd: add support for remapped PPI interrupts
In reply to Marc ZyngierWhen CONFIG_ARM_GIC_VPPI is enabled, let smp_twd request interrupts the normal way (ie using request_irq()).
This involves letting PPIs go via the same code path as SPIs and having normal interrupt handler for the local timer code.
The previous ad-hoc code is still supported when CONFIG_ARM_GIC_VPPI is not defined.
--- arch/arm/include/asm/localtimer.h | 6 ++++++ arch/arm/kernel/smp.c | 12 ++++++++++++ arch/arm/kernel/smp_twd.c | 20 +++++++++++++++++++- 3 files changed, 37 insertions(+), 1 deletions(-)
arch/arm/include/asm/localtimer.h +6 -0
@@ -10,6 +10,8 @@#ifndef __ASM_ARM_LOCALTIMER_H#define __ASM_ARM_LOCALTIMER_H +#include <linux/interrupt.h> +struct clock_event_device ;/*
@@ -22,6 +24,10 @@ void percpu_timer_setup(void);*/ asmlinkage void do_local_timer(struct pt_regs *); +/* +* Per-cpu timer IRQ handler +*/ +irqreturn_t percpu_timer_handler (int irq,void *dev_id);#ifdef CONFIG_LOCAL_TIMERS
arch/arm/kernel/smp.c +12 -0
@@ -452,6 +452,18 @@ asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs)set_irq_regs (old_regs); } +irqreturn_t percpu_timer_handler (int irq,void *dev_id) +{ +struct clock_event_device *evt = dev_id; + +if (local_timer_ack ()) { + evt->event_handler (evt); +return IRQ_HANDLED ; + } + +return IRQ_NONE ; +} +void show_local_irqs (struct seq_file *p,int prec) {unsigned int cpu;
arch/arm/kernel/smp_twd.c +19 -1
@@ -15,10 +15,11 @@#include <linux/smp.h> #include <linux/jiffies.h> #include <linux/clockchips.h> -#include <linux/irq.h> +#include <linux/interrupt.h> #include <linux/io.h> #include <asm/smp_twd.h> +#include <asm/localtimer.h> #include <asm/hardware/gic.h> /* set up by the platform code */
@@ -43,6 +44,10 @@ static void twd_set_mode(enum clock_event_mode mode, ctrl =TWD_TIMER_CONTROL_IT_ENABLE |TWD_TIMER_CONTROL_ONESHOT ;break ;case CLOCK_EVT_MODE_UNUSED : +#ifdef CONFIG_ARM_GIC_VPPI +free_irq (clk->irq, clk); +/* fall through */ +#endif case CLOCK_EVT_MODE_SHUTDOWN :default : ctrl =0 ;
@@ -124,6 +129,8 @@ static void __cpuinit twd_calibrate_rate(void)*/ void __cpuinit twd_timer_setup (struct clock_event_device *clk) { +int err; +twd_calibrate_rate (); clk->name ="local_timer" ;
@@ -137,8 +144,19 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk) clk->max_delta_ns =clockevent_delta2ns (0xffffffff , clk); clk->min_delta_ns =clockevent_delta2ns (0xf , clk); +#ifdef CONFIG_ARM_GIC_VPPI + err =request_irq (clk->irq, percpu_timer_handler, +IRQF_PERCPU |IRQF_NOBALANCING |IRQF_TIMER , + clk->name, clk); +if (err) { +pr_err ("%s: can't register interrupt %d on cpu %d (%d)\n" , + clk->name, clk->irq,smp_processor_id (), err); +return ; + } +#else /* Make sure our local interrupt controller has this enabled */ gic_enable_ppi (clk->irq); +#endif clockevents_register_device (clk); }
Signature · 1 line
1.7.0.4
RFC PATCH v2 2/12 ARM: smp_twd: add support for remapped PPI interrupts
Quoted 10 lines · Marc Zyngier
arch/arm/kernel/smp.c +2
-0@@ -452,6 +452,18 @@ asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs)set_irq_regs (old_regs); } +irqreturn_t percpu_timer_handler (int irq,void *dev_id) +{
arch/arm/kernel/smp.c asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs) · line 466
Quoted 10 lines
arch/arm/kernel/smp.c +10
-0+struct clock_event_device *evt = dev_id; + +if (local_timer_ack ()) { + evt->event_handler (evt); +return IRQ_HANDLED ; + } + +return IRQ_NONE ; +} +
MSM needs this second patch again. I suppose it's not titled correctly? I'd rather not have MSM use this function at all though. Perhaps its better to just hide this in smp_twd.c along with local_timer_ack()?
What is going on with mach-exynos4/mct.c? Their local_timer_ack() is a return 0 and they do a setup_irq() in their local_timer_setup() path. That all seems very broken and I would be surprised if hotplug and local timer stats worked on that system.
Signature · 2 lines
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
RFC PATCH v2 2/12 ARM: smp_twd: add support for remapped PPI interrupts
Quoted 9 lines · Stephen Boyd
Quoted 8 lines · Marc Zyngier
arch/arm/kernel/smp.c +0
-0@@ -452,6 +452,18 @@ asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs)set_irq_regs (old_regs); }
Quoted 16 lines
arch/arm/kernel/smp.c asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs) · line 466
Quoted 12 lines
arch/arm/kernel/smp.c +12
-0+irqreturn_t percpu_timer_handler (int irq,void *dev_id) +{ +struct clock_event_device *evt = dev_id; + +if (local_timer_ack ()) { + evt->event_handler (evt); +return IRQ_HANDLED ; + } + +return IRQ_NONE ; +} +MSM needs this second patch again. I suppose it's not titled correctly? I'd rather not have MSM use this function at all though. Perhaps its better to just hide this in
smp_twd.calong withlocal_timer_ack()?
I'd like to keep the handler in a separate file, as I have an additional patch set for the A15 timers that are using the same handler.
Quoted 4 lines
What is going on with
mach-exynos4/mct.c? Theirlocal_timer_ack()is a return 0 and they do asetup_irq()in theirlocal_timer_setup()path. That all seems very broken and I would be surprised if hotplug and local timer stats worked on that system.
MCT is an odd case. They're using SPI, not PPI, and local_timer_ack() is only present to please the linker (never called).
Could probably have them to converge as well.
M.
Signature · 3 lines
Reality is an implementation detail. -- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
RFC PATCH v2 3/12 ARM: omap4: use remapped PPI interrupts for local timer
In reply to Marc ZyngierUse the normal interrupt scheme for the local timers by using a remapped PPI interrupt.
Tested on a Pandaboard.
--- arch/arm/mach-omap2/Kconfig | 1 + arch/arm/mach-omap2/include/mach/entry-macro.S | 14 +------------- arch/arm/mach-omap2/timer-mpu.c | 3 ++- 3 files changed, 4 insertions(+), 14 deletions(-)
arch/arm/mach-omap2/Kconfig +1 -0
@@ -44,6 +44,7 @@ config ARCH_OMAP4 depends on ARCH_OMAP2PLUS select CPU_V7 select ARM_GIC + select ARM_GIC_VPPI select LOCAL_TIMERS if SMP select PL310_ERRATA_588369 select PL310_ERRATA_727915
arch/arm/mach-omap2/include/mach/entry-macro.S +1 -13
@@ -78,7 +78,7 @@ 4401: ldr \irqstat, [\base, #GIC_CPU_INTACK] ldr \tmp, =1021 bic \irqnr, \irqstat, #0x1c00 - cmp \irqnr, #29 + cmp \irqnr, #15 cmpcc \irqnr, \irqnr cmpne \irqnr, \tmp cmpcs \irqnr, \irqnr
@@ -101,18 +101,6 @@ it cs cmpcs \irqnr, \irqnr .endm - - /* As above, this assumes that irqstat and base are preserved */ - - .macro test_for_ltirq, irqnr, irqstat, base, tmp - bic \irqnr, \irqstat, #0x1c00 - mov \tmp, #0 - cmp \irqnr, #29 - itt eq - moveq \tmp, #1 - streq \irqstat, [\base, #GIC_CPU_EOI] - cmp \tmp, #0 - .endm #endif /* CONFIG_SMP */ #else /* MULTI_OMAP2 */
arch/arm/mach-omap2/timer-mpu.c +2 -1
@@ -22,6 +22,7 @@#include <asm/irq.h> #include <asm/smp_twd.h> #include <asm/localtimer.h> +#include <asm/hardware/gic.h> /* * Setup the local clock events for a CPU.
@@ -32,7 +33,7 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt)if (omap_rev () ==OMAP4430_REV_ES1_0 )return -ENXIO ; - evt->irq =OMAP44XX_IRQ_LOCALTIMER ; + evt->irq =gic_ppi_to_vppi (OMAP44XX_IRQ_LOCALTIMER );twd_timer_setup (evt);return 0 ; }
Signature · 1 line
1.7.0.4
RFC PATCH v2 4/12 ARM: versatile: use remapped PPI interrupts for local timer
In reply to Marc ZyngierUse the normal interrupt scheme for the local timers by using a remapped PPI interrupt.
Tested on VExpress and PB-11MP.
--- arch/arm/mach-realview/Kconfig | 2 ++ arch/arm/mach-vexpress/Kconfig | 1 + arch/arm/plat-versatile/localtimer.c | 3 ++- 3 files changed, 5 insertions(+), 1 deletions(-)
arch/arm/mach-realview/Kconfig +2 -0
@@ -38,6 +38,7 @@ config MACH_REALVIEW_PB11MP bool "Support RealView(R) Platform Baseboard for ARM11MPCore" select CPU_V6K select ARM_GIC + select ARM_GIC_VPPI select HAVE_PATA_PLATFORM select ARCH_HAS_BARRIERS if SMP help
@@ -76,6 +77,7 @@ config MACH_REALVIEW_PBA8 config MACH_REALVIEW_PBX bool "Support RealView(R) Platform Baseboard Explore" select ARM_GIC + select ARM_GIC_VPPI select HAVE_PATA_PLATFORM select ARCH_SPARSEMEM_ENABLE if CPU_V7 && !REALVIEW_HIGH_PHYS_OFFSET select ZONE_DMA if SPARSEMEM
arch/arm/mach-vexpress/Kconfig +1 -0
@@ -5,6 +5,7 @@ config ARCH_VEXPRESS_CA9X4 bool "Versatile Express Cortex-A9x4 tile" select CPU_V7 select ARM_GIC + select ARM_GIC_VPPI select ARM_ERRATA_720789 select ARM_ERRATA_751472 select ARM_ERRATA_753970
arch/arm/plat-versatile/localtimer.c +2 -1
@@ -14,6 +14,7 @@#include <asm/smp_twd.h> #include <asm/localtimer.h> +#include <asm/hardware/gic.h> #include <mach/irqs.h> /*
@@ -21,7 +22,7 @@*/ int __cpuinit local_timer_setup (struct clock_event_device *evt) { - evt->irq =IRQ_LOCALTIMER ; + evt->irq =gic_ppi_to_vppi (IRQ_LOCALTIMER );twd_timer_setup (evt);return 0 ; }
Signature · 1 line
1.7.0.4
RFC PATCH v2 5/12 ARM: shmobile: use remapped PPI interrupts for local timer
In reply to Marc ZyngierUse the normal interrupt scheme for the local timers by using a remapped PPI interrupt.
--- arch/arm/mach-shmobile/Kconfig | 1 + arch/arm/mach-shmobile/entry-intc.S | 3 --- arch/arm/mach-shmobile/include/mach/entry-macro.S | 3 --- arch/arm/mach-shmobile/localtimer.c | 3 ++- 4 files changed, 3 insertions(+), 7 deletions(-)
arch/arm/mach-shmobile/Kconfig +1 -0
@@ -26,6 +26,7 @@ config ARCH_SH73A0 select SH_CLK_CPG select ARCH_WANT_OPTIONAL_GPIOLIB select ARM_GIC + select ARM_GIC_VPPI comment "SH-Mobile Board Type"
arch/arm/mach-shmobile/entry-intc.S +0 -3
@@ -51,7 +51,4 @@ .macro test_for_ipi, irqnr, irqstat, base, tmp .endm - .macro test_for_ltirq, irqnr, irqstat, base, tmp - .endm - arch_irq_handler shmobile_handle_irq_intc
arch/arm/mach-shmobile/include/mach/entry-macro.S +0 -3
@@ -27,8 +27,5 @@ .macro test_for_ipi, irqnr, irqstat, base, tmp .endm - .macro test_for_ltirq, irqnr, irqstat, base, tmp - .endm - .macro arch_ret_to_user, tmp1, tmp2 .endm
arch/arm/mach-shmobile/localtimer.c +2 -1
@@ -14,13 +14,14 @@#include <linux/clockchips.h> #include <asm/smp_twd.h> #include <asm/localtimer.h> +#include <asm/hardware/gic.h> /* * Setup the local clock events for a CPU. */ int __cpuinit local_timer_setup (struct clock_event_device *evt) { - evt->irq =29 ; + evt->irq =gic_ppi_to_vppi (29 );twd_timer_setup (evt);return 0 ; }
Signature · 1 line
1.7.0.4
RFC PATCH v2 6/12 ARM: ux500: use remapped PPI interrupts for local timer
In reply to Marc ZyngierUse the normal interrupt scheme for the local timers by using a remapped PPI interrupt.
--- arch/arm/mach-ux500/Kconfig | 1 + arch/arm/mach-ux500/localtimer.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletions(-)
arch/arm/mach-ux500/Kconfig +1 -0
@@ -4,6 +4,7 @@ config UX500_SOC_COMMON bool default y select ARM_GIC + select ARM_GIC_VPPI select HAS_MTU select NOMADIK_GPIO select ARM_ERRATA_753970
arch/arm/mach-ux500/localtimer.c +2 -1
@@ -17,13 +17,14 @@#include <asm/irq.h> #include <asm/smp_twd.h> #include <asm/localtimer.h> +#include <asm/hardware/gic.h> /* * Setup the local clock events for a CPU. */ int __cpuinit local_timer_setup (struct clock_event_device *evt) { - evt->irq =IRQ_LOCALTIMER ; + evt->irq =gic_ppi_to_vppi (IRQ_LOCALTIMER );twd_timer_setup (evt);return 0 ; }
Signature · 1 line
1.7.0.4
RFC PATCH v2 7/12 ARM: tegra: use remapped PPI interrupts for local timer
In reply to Marc ZyngierUse the normal interrupt scheme for the local timers by using a remapped PPI interrupt.
--- arch/arm/mach-tegra/Kconfig | 1 + arch/arm/mach-tegra/localtimer.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletions(-)
arch/arm/mach-tegra/Kconfig +1 -0
@@ -9,6 +9,7 @@ config ARCH_TEGRA_2x_SOC bool "Tegra 2 family" select CPU_V7 select ARM_GIC + select ARM_GIC_VPPI select ARCH_REQUIRE_GPIOLIB select USB_ARCH_HAS_EHCI if USB_SUPPORT select USB_ULPI if USB_SUPPORT
arch/arm/mach-tegra/localtimer.c +2 -1
@@ -14,13 +14,14 @@#include <asm/irq.h> #include <asm/smp_twd.h> #include <asm/localtimer.h> +#include <asm/hardware/gic.h> /* * Setup the local clock events for a CPU. */ int __cpuinit local_timer_setup (struct clock_event_device *evt) { - evt->irq =IRQ_LOCALTIMER ; + evt->irq =gic_ppi_to_vppi (IRQ_LOCALTIMER );twd_timer_setup (evt);return 0 ; }
Signature · 1 line
1.7.0.4
RFC PATCH v2 8/12 ARM: msm: use remapped PPI interrupts for local timer
In reply to Marc ZyngierUse the normal interrupt scheme for the local timers by using a remapped PPI interrupt.
MSM already had a very similar scheme, though still mixing both GIC-specific and generic APIs.
Fixes and ideas courtesy of Stephen Boyd.
--- arch/arm/mach-msm/Kconfig | 2 + arch/arm/mach-msm/board-msm8x60.c | 11 --- arch/arm/mach-msm/include/mach/entry-macro-qgic.S | 73 +-------------------- arch/arm/mach-msm/timer.c | 62 ++++++++---------- 4 files changed, 30 insertions(+), 118 deletions(-)
arch/arm/mach-msm/Kconfig +2 -0
@@ -42,6 +42,7 @@ config ARCH_MSM8X60 && !MACH_MSM8X60_FFA) select ARCH_MSM_SCORPIONMP select ARM_GIC + select ARM_GIC_VPPI select CPU_V7 select MSM_V2_TLMM select MSM_GPIOMUX
@@ -52,6 +53,7 @@ config ARCH_MSM8960 select ARCH_MSM_SCORPIONMP select MACH_MSM8960_SIM if (!MACH_MSM8960_RUMI3) select ARM_GIC + select ARM_GIC_VPPI select CPU_V7 select MSM_V2_TLMM select MSM_GPIOMUX
arch/arm/mach-msm/board-msm8x60.c +0 -11
@@ -36,8 +36,6 @@ static void __init msm8x60_map_io(void)static void __init msm8x60_init_irq (void ) { -unsigned int i; -gic_init (0 ,GIC_PPI_START ,MSM_QGIC_DIST_BASE , (void *)MSM_QGIC_CPU_BASE );
@@ -49,15 +47,6 @@ static void __init msm8x60_init_irq(void)*/ if (!machine_is_msm8x60_sim ())writel (0x0000FFFF ,MSM_QGIC_DIST_BASE +GIC_DIST_ENABLE_SET ); - -/* FIXME: Not installing AVS_SVICINT and AVS_SVICINTSWDONE yet -* as they are configured as level, which does not play nice with -* handle_percpu_irq. -*/ -for (i =GIC_PPI_START ; i <GIC_SPI_START ; i++) { -if (i !=AVS_SVICINT && i !=AVS_SVICINTSWDONE ) -irq_set_handler (i, handle_percpu_irq); - } }static void __init msm8x60_init (void )
arch/arm/mach-msm/include/mach/entry-macro-qgic.S +1 -72
82 lines not on this page · raw message
arch/arm/mach-msm/timer.c +27 -35
134 lines not on this page · raw message
Signature · 1 line
1.7.0.4
RFC PATCH v2 8/12 ARM: msm: use remapped PPI interrupts for local timer
Quoted 7 lines · Marc Zyngier
arch/arm/mach-msm/timer.c +0
-0@@ -83,18 +85,7 @@ enum {
arch/arm/mach-msm/timer.c enum { · line 94
Quoted 10 lines
arch/arm/mach-msm/timer.c +0
-9static struct msm_clock msm_clocks[]; -static struct clock_event_device *local_clock_event; - -static irqreturn_t msm_timer_interrupt (int irq,void *dev_id) -{ -struct clock_event_device *evt = dev_id; -if (smp_processor_id () !=0 ) - evt = local_clock_event; -if (evt->event_handler ==NULL ) -return IRQ_HANDLED ;
We just lost this important line. This prevents spurious interrupts from crashing the system.
arch/arm/mach-msm/timer.c enum { · line 97
Quoted 3 lines
arch/arm/mach-msm/timer.c +0
-3- evt->event_handler (evt); -return IRQ_HANDLED ; -}
I would prefer to keep the whole interrupt function because 1) MSM doesn't have a local_timer_ack() to implement and 2) I want to put code in here to stop the timer so that the timer doesn't wrap and cause another interrupt (yes the patches haven't been sent yet).
arch/arm/mach-msm/timer.c static void msm_timer_set_mode(enum clock_event_mode mode, · line 134
Quoted 9 lines
arch/arm/mach-msm/timer.c +2
-0+static int local_timer_inited;static cycle_t msm_read_timer_count (struct clocksource *cs) {@@ -140,6 +131,8 @@ static void msm_timer_set_mode(enum clock_event_mode mode,writel (TIMER_ENABLE_EN , clock->regbase +TIMER_ENABLE );break ;case CLOCK_EVT_MODE_UNUSED : +free_irq (evt->irq, evt);
This is crashing because evt->irq is never assigned in the case of CPU0's timer.
arch/arm/mach-msm/timer.c static void __init msm_timer_init(void) · line 241
Quoted 9 lines
arch/arm/mach-msm/timer.c +4
-1@@ -253,10 +235,13 @@ static void __init msm_timer_init(void)printk (KERN_ERR "msm_timer_init: clocksource_register " "failed for %s\n" , cs->name); - res =setup_irq (clock->irq.irq, &clock->irq); + irq =gic_ppi_to_vppi (clock->irq); + res =request_irq (irq, percpu_timer_handler, +IRQF_TIMER |IRQF_NOBALANCING |IRQF_TRIGGER_RISING , + ce->name, ce);
How about assigning evt->irq to gic_ppi_to_vppi() and then use that instead of a local variable? That would fix the free_irq() bug up above.
Also, percpu_timer_handler() is only defined in arm/kernel/smp.c which isn't going to be compiled in on non-SMP targets. This timer driver is common to all MSMs so it needs to work with SMP and non-SMP.
Signature · 2 lines
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
RFC PATCH v2 8/12 ARM: msm: use remapped PPI interrupts for local timer
Quoted 8 lines · Stephen Boyd
Quoted 7 lines · Marc Zyngier
arch/arm/mach-msm/timer.c +0
-0@@ -83,18 +85,7 @@ enum {
Quoted 13 lines
arch/arm/mach-msm/timer.c enum { · line 94
Quoted 10 lines
arch/arm/mach-msm/timer.c +0
-9static struct msm_clock msm_clocks[]; -static struct clock_event_device *local_clock_event; - -static irqreturn_t msm_timer_interrupt (int irq,void *dev_id) -{ -struct clock_event_device *evt = dev_id; -if (smp_processor_id () !=0 ) - evt = local_clock_event; -if (evt->event_handler ==NULL ) -return IRQ_HANDLED ;We just lost this important line. This prevents spurious interrupts from crashing the system.
Is this something you actually see on a real system, or just a guard in case something goes horribly wrong?
Quoted 8 lines
arch/arm/mach-msm/timer.c enum { · line 97
Quoted 3 lines
arch/arm/mach-msm/timer.c +0
-3- evt->event_handler (evt); -return IRQ_HANDLED ; -}I would prefer to keep the whole interrupt function because 1) MSM doesn't have a
local_timer_ack()to implement and 2) I want to put code in here to stop the timer so that the timer doesn't wrap and cause another interrupt (yes the patches haven't been sent yet).
I was thinking of reusing the local_timer_ack() for that, possibly passing some useful parameters (evt, cpu...). I'd really like the event_handler() call to become common code, and move everything else to the local_timer_ack() method (with a possible empty default implemented as a weak symbol).
Quoted 17 lines
arch/arm/mach-msm/timer.c static void msm_timer_set_mode(enum clock_event_mode mode, · line 134
Quoted 9 lines
arch/arm/mach-msm/timer.c +2
-0+static int local_timer_inited;static cycle_t msm_read_timer_count (struct clocksource *cs) {@@ -140,6 +131,8 @@ static void msm_timer_set_mode(enum clock_event_mode mode,writel (TIMER_ENABLE_EN , clock->regbase +TIMER_ENABLE );break ;case CLOCK_EVT_MODE_UNUSED : +free_irq (evt->irq, evt);This is crashing because
evt->irqis never assigned in the case of CPU0's timer.Quoted 4 lines
arch/arm/mach-msm/timer.c +0
-0@@ -253,10 +235,13 @@ static void __init msm_timer_init(void)printk (KERN_ERR "msm_timer_init: clocksource_register " "failed for %s\n" , cs->name);
Quoted 8 lines
arch/arm/mach-msm/timer.c static void __init msm_timer_init(void) · line 241
Quoted 5 lines
arch/arm/mach-msm/timer.c +4
-1- res =setup_irq (clock->irq.irq, &clock->irq); + irq =gic_ppi_to_vppi (clock->irq); + res =request_irq (irq, percpu_timer_handler, +IRQF_TIMER |IRQF_NOBALANCING |IRQF_TRIGGER_RISING , + ce->name, ce);How about assigning
evt->irqtogic_ppi_to_vppi()and then use that instead of a local variable? That would fix thefree_irq()bug up above.
Indeed. Fixed.
Quoted 3 lines
Also,
percpu_timer_handler()is only defined inarm/kernel/smp.cwhich isn't going to be compiled in on non-SMP targets. This timer driver is common to all MSMs so it needs to work with SMP and non-SMP.
My plan is to move most (if not all) of the timer stuff out of smp.c, as A15 has the same requirements as MSM (local timers are used even on non-smp configurations). I'll introduce that earlier than expected, then.
Expect a v3 shortly...
Thanks for reviewing,
M.
Signature · 1 line
Reality is an implementation detail.
RFC PATCH v2 8/12 ARM: msm: use remapped PPI interrupts for local timer
Quoted 21 lines · Marc Zyngier
Quoted 8 lines · Stephen Boyd
Quoted 7 lines · Marc Zyngier
arch/arm/mach-msm/timer.c +0
-0@@ -83,18 +85,7 @@ enum {Quoted 12 lines
arch/arm/mach-msm/timer.c enum { · line 94
Quoted 10 lines
arch/arm/mach-msm/timer.c +0
-9static struct msm_clock msm_clocks[]; -static struct clock_event_device *local_clock_event; - -static irqreturn_t msm_timer_interrupt (int irq,void *dev_id) -{ -struct clock_event_device *evt = dev_id; -if (smp_processor_id () !=0 ) - evt = local_clock_event; -if (evt->event_handler ==NULL ) -return IRQ_HANDLED ;We just lost this important line. This prevents spurious interrupts from crashing the system.
Quoted 3 lines
Is this something you actually see on a real system, or just a guard in case something goes horribly wrong?
I believe a bootloader left a pending interrupt at some point and thus when we request the interrupt before registering the clockevent the interrupt handler will be called and evt->event_handler == NULL. Perhaps we could register the clockevent before registering the interrupt handler? I'm not sure that works. Otherwise we need to clear the interrupt in the GIC or something. Any suggestions?
If it's any consolation, x86 seems to do the same thing presumably for the same reason.
Quoted 7 lines
Quoted 7 lines
arch/arm/mach-msm/timer.c enum { · line 97
Quoted 3 lines
arch/arm/mach-msm/timer.c +0
-3- evt->event_handler (evt); -return IRQ_HANDLED ; -}I would prefer to keep the whole interrupt function because 1) MSM doesn't have a
local_timer_ack()to implement and 2) I want to put code in here to stop the timer so that the timer doesn't wrap and cause another interrupt (yes the patches haven't been sent yet).
Quoted 6 lines
I was thinking of reusing the
local_timer_ack()for that, possibly passing some useful parameters (evt, cpu...). I'd really like theevent_handler()call to become common code, and move everything else to thelocal_timer_ack()method (with a possible empty default implemented as a weak symbol).
Ok. So you're saying there is one interrupt handler that will call down to the hardware specific handler via local_timer_ack()? That sounds like one step backwards when you consider we want to compile many machines into one kernel.
A generic interrupt handler for simple timers where there is nothing to do besides call the event handler is probably good consolidation. But if the hardware requires something else, it doesn't seem so bad to write your own.
What's the use of local_timer_ack() in the scheme of this patch series again? I was really hoping that function would go away.
Signature · 2 lines
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
RFC PATCH v2 8/12 ARM: msm: use remapped PPI interrupts for local timer
Quoted 26 lines · Stephen Boyd
Quoted 21 lines · Marc Zyngier
Quoted 8 lines · Stephen Boyd
Quoted 7 lines · Marc Zyngier
arch/arm/mach-msm/timer.c +0
-0@@ -83,18 +85,7 @@ enum {Quoted 12 lines
arch/arm/mach-msm/timer.c enum { · line 94
Quoted 10 lines
arch/arm/mach-msm/timer.c +0
-9static struct msm_clock msm_clocks[]; -static struct clock_event_device *local_clock_event; - -static irqreturn_t msm_timer_interrupt (int irq,void *dev_id) -{ -struct clock_event_device *evt = dev_id; -if (smp_processor_id () !=0 ) - evt = local_clock_event; -if (evt->event_handler ==NULL ) -return IRQ_HANDLED ;We just lost this important line. This prevents spurious interrupts from crashing the system.
Quoted 3 lines
Is this something you actually see on a real system, or just a guard in case something goes horribly wrong?
Quoted 6 lines
I believe a bootloader left a pending interrupt at some point and thus when we request the interrupt before registering the clockevent the interrupt handler will be called and
evt->event_handler== NULL. Perhaps we could register the clockevent before registering the interrupt handler? I'm not sure that works. Otherwise we need to clear the interrupt in the GIC or something. Any suggestions?
The generic code could install a dummy event_handler before calling into the platform code. That way, no need to test for this on the hot path.
Quoted 2 lines
If it's any consolation, x86 seems to do the same thing presumably for the same reason.
Oh well... ;-)
Quoted 14 lines
Quoted 7 lines
Quoted 7 lines
arch/arm/mach-msm/timer.c enum { · line 97
Quoted 3 lines
arch/arm/mach-msm/timer.c +0
-3- evt->event_handler (evt); -return IRQ_HANDLED ; -}I would prefer to keep the whole interrupt function because 1) MSM doesn't have a
local_timer_ack()to implement and 2) I want to put code in here to stop the timer so that the timer doesn't wrap and cause another interrupt (yes the patches haven't been sent yet).Quoted 6 lines
I was thinking of reusing the
local_timer_ack()for that, possibly passing some useful parameters (evt, cpu...). I'd really like theevent_handler()call to become common code, and move everything else to thelocal_timer_ack()method (with a possible empty default implemented as a weak symbol).
Quoted 4 lines
Ok. So you're saying there is one interrupt handler that will call down to the hardware specific handler via
local_timer_ack()? That sounds like one step backwards when you consider we want to compile many machines into one kernel.
That would only be an interim hack. I proposed a solution for that a while ago, as part of my A15 timer series:
http://www.spinics.net/lists/arm-kernel/msg118579.html
Basically, you register a set of function pointers with the core timer code, local_timer_ack() being one of them. If you do not provide one, even better.
That gives you a way to register your timer at runtime (I have the same binary kernel running on A5 using TWD and A15 using the architected timers).
Quoted 7 lines
A generic interrupt handler for simple timers where there is nothing to do besides call the event handler is probably good consolidation. But if the hardware requires something else, it doesn't seem so bad to write your own.
What's the use of
local_timer_ack()in the scheme of this patch series again? I was really hoping that function would go away.
Maybe this is a bit out of the scope of this patch series, actually. I'll drop this change, and will create another series only impacting local_ack()/interrupt handler.
Cheers,
M.
Signature · 1 line
Reality is an implementation detail.
RFC PATCH v2 9/12 ARM: exynos4: use remapped PPI interrupts for local timer
In reply to Marc ZyngierUse the normal interrupt scheme for the local timers by using a remapped PPI interrupt.
Tested on a SMDK-S5PV310 board.
--- arch/arm/mach-exynos4/include/mach/entry-macro.S | 12 +----------- arch/arm/mach-exynos4/localtimer.c | 3 ++- arch/arm/plat-s5p/Kconfig | 1 + 3 files changed, 4 insertions(+), 12 deletions(-)
arch/arm/mach-exynos4/include/mach/entry-macro.S +1 -11
@@ -50,7 +50,7 @@ bic \irqnr, \irqstat, #0x1c00 - cmp \irqnr, #29 + cmp \irqnr, #15 cmpcc \irqnr, \irqnr cmpne \irqnr, \tmp cmpcs \irqnr, \irqnr
@@ -72,13 +72,3 @@ cmpcs \irqnr, \irqnr .endm - /* As above, this assumes that irqstat and base are preserved.. */ - - .macro test_for_ltirq, irqnr, irqstat, base, tmp - bic \irqnr, \irqstat, #0x1c00 - mov \tmp, #0 - cmp \irqnr, #29 - moveq \tmp, #1 - streq \irqstat, [\base, #GIC_CPU_EOI] - cmp \tmp, #0 - .endm
arch/arm/mach-exynos4/localtimer.c +2 -1
@@ -14,13 +14,14 @@#include <asm/irq.h> #include <asm/localtimer.h> +#include <asm/hardware/gic.h> /* * Setup the local clock events for a CPU. */ int __cpuinit local_timer_setup (struct clock_event_device *evt) { - evt->irq =IRQ_LOCALTIMER ; + evt->irq =gic_ppi_to_vppi (IRQ_LOCALTIMER );twd_timer_setup (evt);return 0 ; }
arch/arm/plat-s5p/Kconfig +1 -0
@@ -11,6 +11,7 @@ config PLAT_S5P default y select ARM_VIC if !ARCH_EXYNOS4 select ARM_GIC if ARCH_EXYNOS4 + select ARM_GIC_VPPI if ARCH_EXYNOS4 select NO_IOPORT select ARCH_REQUIRE_GPIOLIB select S3C_GPIO_TRACK
Signature · 1 line
1.7.0.4
RFC PATCH v2 10/12 ARM: gic: remove previous local timer interrupt handling
In reply to Marc ZyngierNow that all users of local timers are using CONFIG_ARM_GIC_VPPI, the now unused local timer infrastructure can be safely removed.
--- arch/arm/common/gic.c | 10 -------- arch/arm/include/asm/entry-macro-multi.S | 7 ----- arch/arm/include/asm/hardirq.h | 3 -- arch/arm/include/asm/hardware/entry-macro-gic.S | 13 ---------- arch/arm/include/asm/hardware/gic.h | 1 - arch/arm/include/asm/localtimer.h | 5 ---- arch/arm/include/asm/smp.h | 5 ---- arch/arm/kernel/irq.c | 3 -- arch/arm/kernel/smp.c | 29 ----------------------- arch/arm/kernel/smp_twd.c | 7 ----- 10 files changed, 0 insertions(+), 83 deletions(-)
arch/arm/common/gic.c +0 -10
@@ -501,16 +501,6 @@ void __cpuinit gic_secondary_init(unsigned int gic_nr)gic_cpu_init (&gic_data[gic_nr]); } -void __cpuinit gic_enable_ppi (unsigned int irq) -{ -unsigned long flags; - -local_irq_save (flags); -irq_set_status_flags (irq,IRQ_NOPROBE ); -gic_unmask_irq (irq_get_irq_data (irq)); -local_irq_restore (flags); -} -#ifdef CONFIG_SMP void gic_raise_softirq (const struct cpumask *mask,unsigned int irq) {
arch/arm/include/asm/entry-macro-multi.S +0 -7
@@ -23,13 +23,6 @@ movne r1, sp adrne lr, BSYM(1b) bne do_IPI - -#if defined(CONFIG_LOCAL_TIMERS) && !defined(CONFIG_ARM_GIC_VPPI) - test_for_ltirq r0, r6, r5, lr - movne r0, sp - adrne lr, BSYM(1b) - bne do_local_timer -#endif #endif 9997: .endm
arch/arm/include/asm/hardirq.h +0 -3
@@ -9,9 +9,6 @@ typedef struct { unsigned int __softirq_pending; -#ifdef CONFIG_LOCAL_TIMERS - unsigned int local_timer_irqs; -#endif #ifdef CONFIG_SMP unsigned int ipi_irqs[NR_IPI]; #endif
arch/arm/include/asm/hardware/entry-macro-gic.S +0 -13
@@ -65,16 +65,3 @@ strcc \irqstat, [\base, #GIC_CPU_EOI] cmpcs \irqnr, \irqnr .endm - -#ifndef CONFIG_ARM_GIC_VPPI -/* As above, this assumes that irqstat and base are preserved.. */ - - .macro test_for_ltirq, irqnr, irqstat, base, tmp - bic \irqnr, \irqstat, #0x1c00 - mov \tmp, #0 - cmp \irqnr, #29 - moveq \tmp, #1 - streq \irqstat, [\base, #GIC_CPU_EOI] - cmp \tmp, #0 - .endm -#endif
arch/arm/include/asm/hardware/gic.h +0 -1
@@ -42,7 +42,6 @@ void gic_init(unsigned int, unsigned int, void __iomem *, void __iomem *);void gic_secondary_init (unsigned int );void gic_cascade_irq (unsigned int gic_nr,unsigned int irq);void gic_raise_softirq (const struct cpumask *mask,unsigned int irq); -void gic_enable_ppi (unsigned int );#ifdef CONFIG_ARM_GIC_VPPI unsigned int gic_ppi_to_vppi (unsigned int irq);#else
arch/arm/include/asm/localtimer.h +0 -5
@@ -20,11 +20,6 @@ struct clock_event_device;void percpu_timer_setup (void );/* -* Called from assembly, this is the local timer IRQ handler -*/ -asmlinkage void do_local_timer(struct pt_regs *); - -/* * Per-cpu timer IRQ handler */ irqreturn_t percpu_timer_handler (int irq,void *dev_id);
arch/arm/include/asm/smp.h +0 -5
@@ -95,9 +95,4 @@ extern void platform_cpu_enable(unsigned int cpu);extern void arch_send_call_function_single_ipi (int cpu);extern void arch_send_call_function_ipi_mask (const struct cpumask *mask); -/* -* show local interrupt info -*/ -extern void show_local_irqs (struct seq_file *,int ); -#endif /* ifndef __ASM_ARM_SMP_H */
arch/arm/kernel/irq.c +0 -3
@@ -59,9 +59,6 @@ int arch_show_interrupts(struct seq_file *p, int prec)#ifdef CONFIG_SMP show_ipi_list (p, prec);#endif -#ifdef CONFIG_LOCAL_TIMERS -show_local_irqs (p, prec); -#endif seq_printf (p,"%*s: %10lu\n" , prec,"Err" , irq_err_count);return 0 ; }
arch/arm/kernel/smp.c +0 -29
@@ -418,10 +418,6 @@ u64 smp_irq_stat_cpu(unsigned int cpu)for (i =0 ; i <NR_IPI ; i++) sum +=__get_irq_stat (cpu, ipi_irqs[i]); -#ifdef CONFIG_LOCAL_TIMERS - sum +=__get_irq_stat (cpu, local_timer_irqs); -#endif -return sum; }
@@ -439,19 +435,6 @@ static void ipi_timer(void) }#ifdef CONFIG_LOCAL_TIMERS -asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs) -{ -struct pt_regs *old_regs =set_irq_regs (regs); -int cpu =smp_processor_id (); - -if (local_timer_ack ()) { -__inc_irq_stat (cpu, local_timer_irqs); -ipi_timer (); - } - -set_irq_regs (old_regs); -} -irqreturn_t percpu_timer_handler (int irq,void *dev_id) {struct clock_event_device *evt = dev_id;
@@ -463,18 +446,6 @@ irqreturn_t percpu_timer_handler(int irq, void *dev_id) return IRQ_NONE; } - -void show_local_irqs (struct seq_file *p,int prec) -{ -unsigned int cpu; - -seq_printf (p,"%*s: " , prec,"LOC" ); - -for_each_present_cpu (cpu) -seq_printf (p,"%10u " ,__get_irq_stat (cpu, local_timer_irqs)); - -seq_printf (p," Local timer interrupts\n" ); -}#endif #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
arch/arm/kernel/smp_twd.c +0 -7
@@ -44,10 +44,8 @@ static void twd_set_mode(enum clock_event_mode mode, ctrl =TWD_TIMER_CONTROL_IT_ENABLE |TWD_TIMER_CONTROL_ONESHOT ;break ;case CLOCK_EVT_MODE_UNUSED : -#ifdef CONFIG_ARM_GIC_VPPI free_irq (clk->irq, clk);/* fall through */ -#endif case CLOCK_EVT_MODE_SHUTDOWN :default : ctrl =0 ;
@@ -144,7 +142,6 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk) clk->max_delta_ns =clockevent_delta2ns (0xffffffff , clk); clk->min_delta_ns =clockevent_delta2ns (0xf , clk); -#ifdef CONFIG_ARM_GIC_VPPI err =request_irq (clk->irq, percpu_timer_handler,IRQF_PERCPU |IRQF_NOBALANCING |IRQF_TIMER , clk->name, clk);
@@ -153,10 +150,6 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk) clk->name, clk->irq, smp_processor_id(), err);return ; } -#else -/* Make sure our local interrupt controller has this enabled */ -gic_enable_ppi (clk->irq); -#endif clockevents_register_device (clk); }
Signature · 1 line
1.7.0.4
RFC PATCH v2 11/12 ARM: gic: add compute_irqnr macro for exynos4
In reply to Marc Zyngierexynos4 has a full copy of entry-macro-gic.S, just for the sake of an offset added to the IRQ number read from the GIC.
Add a compute_irqnr macro to entry-macro-gic.S so that any platform can add it's own hook without having to copy the whole file again.
--- arch/arm/include/asm/hardware/entry-macro-gic.S | 3 + arch/arm/mach-exynos4/include/mach/entry-macro.S | 60 ++-------------------- 2 files changed, 8 insertions(+), 55 deletions(-)
arch/arm/include/asm/hardware/entry-macro-gic.S +3 -0
@@ -50,6 +50,9 @@ cmpcc \irqnr, \irqnr cmpne \irqnr, \tmp cmpcs \irqnr, \irqnr +#ifdef HAVE_GIC_BASE_OFFSET + compute_irqnr \irqnr, \tmp +#endif .endm /* We assume that irqstat (the raw value of the IRQ acknowledge
arch/arm/mach-exynos4/include/mach/entry-macro.S +5 -55
71 lines not on this page · raw message
Signature · 1 line
1.7.0.4
RFC PATCH v2 12/12 ARM: SMP: automatically select ARM_GIC_VPPI
In reply to Marc ZyngierAll SMP platforms are selecting ARM_GIC_VPPI.
Instead, make SMP select ARM_GIC_VPPI and remove select statements from the platform code.
--- arch/arm/Kconfig | 1 + arch/arm/mach-msm/Kconfig | 2 -- arch/arm/mach-omap2/Kconfig | 1 - arch/arm/mach-realview/Kconfig | 2 -- arch/arm/mach-shmobile/Kconfig | 1 - arch/arm/mach-tegra/Kconfig | 1 - arch/arm/mach-ux500/Kconfig | 1 - arch/arm/mach-vexpress/Kconfig | 1 - arch/arm/plat-s5p/Kconfig | 1 - 9 files changed, 1 insertions(+), 10 deletions(-)
arch/arm/Kconfig +1 -0
@@ -1327,6 +1327,7 @@ config SMP ARCH_EXYNOS4 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \ ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE select USE_GENERIC_SMP_HELPERS + select ARM_GIC_VPPI select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP help This enables support for systems with more than one CPU. If you have
arch/arm/mach-msm/Kconfig +0 -2
@@ -42,7 +42,6 @@ config ARCH_MSM8X60 && !MACH_MSM8X60_FFA) select ARCH_MSM_SCORPIONMP select ARM_GIC - select ARM_GIC_VPPI select CPU_V7 select MSM_V2_TLMM select MSM_GPIOMUX
@@ -53,7 +52,6 @@ config ARCH_MSM8960 select ARCH_MSM_SCORPIONMP select MACH_MSM8960_SIM if (!MACH_MSM8960_RUMI3) select ARM_GIC - select ARM_GIC_VPPI select CPU_V7 select MSM_V2_TLMM select MSM_GPIOMUX
arch/arm/mach-omap2/Kconfig +0 -1
@@ -44,7 +44,6 @@ config ARCH_OMAP4 depends on ARCH_OMAP2PLUS select CPU_V7 select ARM_GIC - select ARM_GIC_VPPI select LOCAL_TIMERS if SMP select PL310_ERRATA_588369 select PL310_ERRATA_727915
arch/arm/mach-realview/Kconfig +0 -2
@@ -38,7 +38,6 @@ config MACH_REALVIEW_PB11MP bool "Support RealView(R) Platform Baseboard for ARM11MPCore" select CPU_V6K select ARM_GIC - select ARM_GIC_VPPI select HAVE_PATA_PLATFORM select ARCH_HAS_BARRIERS if SMP help
@@ -77,7 +76,6 @@ config MACH_REALVIEW_PBA8 config MACH_REALVIEW_PBX bool "Support RealView(R) Platform Baseboard Explore" select ARM_GIC - select ARM_GIC_VPPI select HAVE_PATA_PLATFORM select ARCH_SPARSEMEM_ENABLE if CPU_V7 && !REALVIEW_HIGH_PHYS_OFFSET select ZONE_DMA if SPARSEMEM
arch/arm/mach-shmobile/Kconfig +0 -1
@@ -26,7 +26,6 @@ config ARCH_SH73A0 select SH_CLK_CPG select ARCH_WANT_OPTIONAL_GPIOLIB select ARM_GIC - select ARM_GIC_VPPI comment "SH-Mobile Board Type"
arch/arm/mach-tegra/Kconfig +0 -1
@@ -9,7 +9,6 @@ config ARCH_TEGRA_2x_SOC bool "Tegra 2 family" select CPU_V7 select ARM_GIC - select ARM_GIC_VPPI select ARCH_REQUIRE_GPIOLIB select USB_ARCH_HAS_EHCI if USB_SUPPORT select USB_ULPI if USB_SUPPORT
arch/arm/mach-ux500/Kconfig +0 -1
@@ -4,7 +4,6 @@ config UX500_SOC_COMMON bool default y select ARM_GIC - select ARM_GIC_VPPI select HAS_MTU select NOMADIK_GPIO select ARM_ERRATA_753970
arch/arm/mach-vexpress/Kconfig +0 -1
@@ -5,7 +5,6 @@ config ARCH_VEXPRESS_CA9X4 bool "Versatile Express Cortex-A9x4 tile" select CPU_V7 select ARM_GIC - select ARM_GIC_VPPI select ARM_ERRATA_720789 select ARM_ERRATA_751472 select ARM_ERRATA_753970
arch/arm/plat-s5p/Kconfig +0 -1
@@ -11,7 +11,6 @@ config PLAT_S5P default y select ARM_VIC if !ARCH_EXYNOS4 select ARM_GIC if ARCH_EXYNOS4 - select ARM_GIC_VPPI if ARCH_EXYNOS4 select NO_IOPORT select ARCH_REQUIRE_GPIOLIB select S3C_GPIO_TRACK
Signature · 1 line
1.7.0.4
v2 cover Consolidating GIC per-cpu interrupts
In reply to Marc ZyngierMarc,
Quoted 15 lines · Marc Zyngier
The current GIC per-cpu interrupt (aka PPIs) suffers from a number of problems:
- It uses a completely separate scheme to handle the interrupts, mostly because the PPI concept doesn't really match the kernel view of an interrupt.
- Some low-level code gets duplicated, as usual...
- At least one platform (msm) has started implementing its own alternative scheme.The proposed solution is to let the GIC code expose the PPIs as something that the kernel can manage. Instead of having a single interrupt number shared on all cores, make the interrupt number be different on each CPU.
Quoted 7 lines
This enables the use of the normal kernel API (
request_irq()and friends) and the elimination of some low level code.This patch set is based on 2.6.39-rc6, and depends on Will Deacon's GIC fasteoi patches. Tested on VExpress, PB-11MP, Pandaboard and SMDK-S5PV310.
Looks like, this series breaks system wide supsend. Please check.
Regards
Santosh
-------
# echo mem > /sys/power/state
[ 37.503112] PM: Syncing filesystems ... done.
[ 37.552032] Freezing user space processes ... (elapsed 0.01 seconds)
done.
[ 37.577545] Freezing remaining freezable tasks ... (elapsed 0.02
seconds) done.
[ 37.616210] PM: suspend of devices complete after 5.187 msecs
[ 37.623657] PM: late suspend of devices complete after 1.403 msecs
[ 37.630187] Disabling non-boot CPUs ...
[ 37.731964] CPU1: shutdown
[ 38.285888] Enabling non-boot CPUs ...
[ 38.291137] CPU1: Booted secondary processor
[ 38.291168] CPU1: Unknown IPI message 0x1
[ 38.291168] local_timer: can't register interrupt 413 on cpu 1 (-16)
[ 38.365112] Unable to handle kernel NULL pointer dereference at
virtual address 0000004c
[ 38.388946] pgd = c0004000
[ 38.391784] [0000004c] *pgd=00000000
[ 38.395538] Internal error: Oops: 805 [#1] SMP
[ 38.400207] last sysfs file: /sys/devices/virtual/vc/vcsa63/dev
[ 38.406433] Modules linked in:
[ 38.409637] CPU: 1 Not tainted (2.6.39-rc5-00099-g9e06a0a #6)
[ 38.416046] PC is at clockevents_program_event+0x60/0xd4
[ 38.421630] LR is at tick_dev_program_event+0x38/0x140
[ 38.427032] pc : [<c00bc270>] lr : [<c00bd730>] psr: 60000193
[ 38.427032] sp : ef885f78 ip : 00000008 fp : 00000000
[ 38.439086] r10: 00000000 r9 : 00000008 r8 : cebb6148
[ 38.444580] r7 : 00000000 r6 : 0076bbcd r5 : 00000000 r4 : 00000000
[ 38.451446] r3 : 00000008 r2 : cebb6148 r1 : 00000000 r0 : cebb6148
[ 38.458282] Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA ARM
Segment kernel
[ 38.466064] Control: 10c53c7d Table: 8000404a DAC: 00000017
[ 38.472076] Process swapper (pid: 0, stack limit = 0xef8842f8)
[ 38.478210] Stack: (0xef885f78 to 0xef886000)
[ 38.482788] 5f60:
00000000 00000000
[ 38.491394] 5f80: 00000001 c00bd730 ce44a57b 00000008 ce44a57b
00000008 cebb6148 00000008
[ 38.499969] 5fa0: ce442e45 00000000 411fc092 c00bd8ac 00000000
00000008 00000000 c1164ef0
[ 38.508575] 5fc0: 00000008 c00be464 00773594 00000000 ce442e45
00000008 ef884000 0000001f
[ 38.517150] 5fe0: 10c03c7d c05f8630 00000000 c005b9a4 00000001
c006bd8c 5e3adbb2 b8403c00
[ 38.525756] [<c00bc270>] (clockevents_program_event+0x60/0xd4) from
[<c00bd730>] (tick_dev_program_event+0x38/0x140)
[ 38.536804] [<c00bd730>] (tick_dev_program_event+0x38/0x140) from
[<c00bd8ac>] (tick_program_event+0x3c/0x48)
[ 38.547241] [<c00bd8ac>] (tick_program_event+0x3c/0x48) from
[<c00be464>] (tick_nohz_restart_sched_tick+0x170/0x1b8)
[ 38.558319] [<c00be464>] (tick_nohz_restart_sched_tick+0x170/0x1b8)
from [<c005b9a4>] (cpu_idle+0xdc/0xf8)
[ 38.568481] [<c005b9a4>] (cpu_idle+0xdc/0xf8) from [<c006bd8c>]
(platform_cpu_die+0x3c/0x50)
[ 38.577331] Code: e0c17007 e3560001 e2d71000 ba000018 (e584304c)
[ 38.583740] ---[ end trace fd37aa01e7ce7dcd ]---
[ 38.588592] Kernel panic - not syncing: Attempted to kill the idle task!
[ 38.595642] CPU0: stopping
[ 38.598510] [<c0060cdc>] (unwind_backtrace+0x0/0xe4) from
[<c00502a4>] (do_IPI+0xb4/0x12c)
[ 38.607208] [<c00502a4>] (do_IPI+0xb4/0x12c) from [<c03f6c9c>]
(__irq_svc+0x3c/0x100)
[ 38.615447] Exception stack(0xc058bf88 to 0xc058bfd0)
[ 38.620727] bf80: c005b948 00000000 c058bfc0
00000000 c058a000 c0034c0c
[ 38.629333] bfa0: c0034c08 c0590ddc 80000000 411fc092 00000000
00000000 00000000 c058bfd0
[ 38.637908] bfc0: c005b948 c005b94c 60000013 ffffffff
[ 38.643218] [<c03f6c9c>] (__irq_svc+0x3c/0x100) from [<c005b94c>]
(cpu_idle+0x84/0xf8)
[ 38.651550] [<c005b94c>] (cpu_idle+0x84/0xf8) from [<c000893c>]
(start_kernel+0x298/0x2f0)
[ 38.660247] [<c000893c>] (start_kernel+0x298/0x2f0) from [<8000803c>]
(0x8000803c)Regards
Santosh
v2 cover Consolidating GIC per-cpu interrupts
On Fri, 13 May 2011 22:36:04 +0530
Santosh Shilimkar <[email protected]> wrote:
Hi Santosh,
Quoted 7 lines
Looks like, this series breaks system wide supsend. Please check.
Regards
Santosh-------
Quoted 14 lines
# echo mem > /sys/power/state [ 37.503112] PM: Syncing filesystems ... done. [ 37.552032] Freezing user space processes ... (elapsed 0.01 seconds) done. [ 37.577545] Freezing remaining freezable tasks ... (elapsed 0.02 seconds) done. [ 37.616210] PM: suspend of devices complete after 5.187 msecs [ 37.623657] PM: late suspend of devices complete after 1.403 msecs [ 37.630187] Disabling non-boot CPUs ... [ 37.731964] CPU1: shutdown [ 38.285888] Enabling non-boot CPUs ... [ 38.291137] CPU1: Booted secondary processor [ 38.291168] CPU1: Unknown IPI message 0x1 [ 38.291168] local_timer: can't register interrupt 413 on cpu 1 (-16)
Blah... We obviously don't stop the timer on secondary CPUs, and then try to request the interrupt again. I'll have a look on Monday.
Thanks for pointing this out.
M.
Signature · 1 line
I'm the slime oozin' out from your TV set...
v2 cover Consolidating GIC per-cpu interrupts
In reply to Santosh ShilimkarHi Santosh,
Quoted 21 lines · Santosh Shilimkar
Marc,
Quoted 18 lines · Marc Zyngier
The current GIC per-cpu interrupt (aka PPIs) suffers from a number of problems:
- It uses a completely separate scheme to handle the interrupts, mostly because the PPI concept doesn't really match the kernel view of an interrupt.
- Some low-level code gets duplicated, as usual...
- At least one platform (msm) has started implementing its own alternative scheme.The proposed solution is to let the GIC code expose the PPIs as something that the kernel can manage. Instead of having a single interrupt number shared on all cores, make the interrupt number be different on each CPU.
This enables the use of the normal kernel API (
request_irq()and friends) and the elimination of some low level code.
Quoted 7 lines
Quoted 4 lines
This patch set is based on 2.6.39-rc6, and depends on Will Deacon's GIC fasteoi patches. Tested on VExpress, PB-11MP, Pandaboard and SMDK-S5PV310.
Looks like, this series breaks system wide supsend. Please check.
Are you sure you're testing with v2? v1 is known to be broken with CPU_HOTPLUG, but v2 should deal with it. Here is a suspend/resume cycle on my Panda:
root at florentine-pogen:~# echo mem>/sys/power/state
[ 136.215667] PM: Syncing filesystems ... done. [ 136.220977] PM: Preparing system for mem sleep [ 136.226989] Freezing user space processes ... (elapsed 0.02 seconds) done. [ 136.257232] Freezing remaining freezable tasks ... (elapsed 0.01 seconds) done. [ 136.280670] PM: Entering mem sleep [ 136.332916] usb 1-1.1: unlink qh8-0001/dfb97460 start 2 [1/0 us] [ 136.339447] usb 1-1.1: usb suspend [ 136.363861] hub 1-1:1.0: hub_suspend [ 136.367614] usb 1-1: unlink qh256-0001/dfa846e0 start 1 [1/0 us] [ 136.373992] usb 1-1: usb suspend [ 136.395111] hub 1-0:1.0: hub_suspend [ 136.398864] usb usb1: bus suspend [ 136.402343] ehci-omap ehci-omap.0: suspend root hub [ 136.408477] PM: suspend of devices complete after 123.748 msecs [ 136.414703] PM: suspend devices took 0.132 seconds [ 136.420135] PM: late suspend of devices complete after 0.427 msecs [ 136.426605] Disabling non-boot CPUs ... [ 136.528137] CPU1: shutdown [ 138.320465] Enabling non-boot CPUs ... [ 138.324737] CPU1: Booted secondary processor [ 138.324737] CPU1: Unknown IPI message 0x1 [ 138.332183] Switched to NOHz mode on CPU #1 [ 138.527862] CPU1 is up [ 138.543518] PM: early resume of devices complete after 0.152 msecs
[ 138.793670] usb usb1: usb resume [ 138.797058] ehci-omap ehci-omap.0: resume root hub [ 138.848022] hub 1-0:1.0: hub_resume [ 138.851684] hub 1-0:1.0: port 1: status 0507 change 0000 [ 138.857299] usb 1-1: usb resume [ 138.894897] ehci-omap ehci-omap.0: GetStatus port:1 status 001005 0 ACK POWER sig=se0 PE CONNECT [ 138.926147] usb 1-1: finish resume [ 138.933868] hub 1-1:1.0: hub_resume [ 138.937591] hub 1-1:1.0: port 1: status 0507 change 0000 [ 138.957489] ehci-omap ehci-omap.0: reused qh dfa846e0 schedule [ 138.963592] usb 1-1: link qh256-0001/dfa846e0 start 1 [1/0 us] [ 138.972991] usb 1-1.1: usb resume [ 139.037353] usb 1-1.1: finish resume [ 139.041259] ehci-omap ehci-omap.0: reused qh dfb97460 schedule [ 139.047363] usb 1-1.1: link qh8-0001/dfb97460 start 2 [1/0 us] [ 139.053649] PM: resume of devices complete after 503.509 msecs [ 139.059936] PM: resume devices took 0.515 seconds [ 139.064880] PM: Finishing wakeup. [ 139.068359] Restarting tasks ... [ 139.071685] hub 1-0:1.0: state 7 ports 3 chg 0000 evt 0000 [ 139.072631] done. [ 139.079681] hub 1-1:1.0: state 7 ports 5 chg 0000 evt 0002
root at florentine-pogen:~#
Seems to be just fine here...
Cheers,
M.
Signature · 3 lines
Reality is an implementation detail. -- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
v2 cover Consolidating GIC per-cpu interrupts
Quoted 29 lines · Marc Zyngier
Hi Santosh,
Quoted 26 lines · Santosh Shilimkar
Marc,
Quoted 22 lines · Marc Zyngier
The current GIC per-cpu interrupt (aka PPIs) suffers from a number of problems:
- It uses a completely separate scheme to handle the interrupts, mostly because the PPI concept doesn't really match the kernel view of an interrupt.
- Some low-level code gets duplicated, as usual...
- At least one platform (msm) has started implementing its own alternative scheme.The proposed solution is to let the GIC code expose the PPIs as something that the kernel can manage. Instead of having a single interrupt number shared on all cores, make the interrupt number be different on each CPU.
This enables the use of the normal kernel API (
request_irq()and friends) and the elimination of some low level code.This patch set is based on 2.6.39-rc6, and depends on Will Deacon's GIC fasteoi patches. Tested on VExpress, PB-11MP, Pandaboard and SMDK-S5PV310.
Quoted 7 lines
Quoted 2 lines
Looks like, this series breaks system wide supsend. Please check.
Are you sure you're testing with v2? v1 is known to be broken with
CPU_HOTPLUG, but v2 should deal with it. Here is a suspend/resume cycle on my Panda:
May be I tried V1 then. Will try your v2 tomorrow and let you know
v2 cover Consolidating GIC per-cpu interrupts
Marc,
Quoted 3 lines · Santosh Shilimkar
Quoted 2 lines · Marc Zyngier
Hi Santosh,
[...]
Quoted 8 lines
Quoted 7 lines
Quoted 2 lines
Looks like, this series breaks system wide supsend. Please check.
Are you sure you're testing with v2? v1 is known to be broken with
CPU_HOTPLUG, but v2 should deal with it. Here is a suspend/resume cycle on my Panda:May be I tried V1 then. Will try your v2 tomorrow and let you know
V2 seems to work with suspend.
Regards
Santosh
v2 cover Consolidating GIC per-cpu interrupts
Quoted 12 lines · Santosh Shilimkar
Marc,
Quoted 3 lines · Santosh Shilimkar
Quoted 2 lines · Marc Zyngier
Hi Santosh,
[...]
Quoted 3 lines
Quoted 3 lines
Quoted 2 lines
Looks like, this series breaks system wide supsend. Please check.
Quoted 7 lines
Quoted 5 lines
Quoted 4 lines
Are you sure you're testing with v2? v1 is known to be broken with
CPU_HOTPLUG, but v2 should deal with it. Here is a suspend/resume cycle on my Panda:May be I tried V1 then. Will try your v2 tomorrow and let you know
V2 seems to work with suspend.
Thanks a lot for testing!
M.
Signature · 1 line
Reality is an implementation detail.