On Wed, Oct 25 2017 at 5:37:24 pm BST, Paul Burton <paul.burton@xxxxxxxx> wrote: > The gic_all_vpes_local_irq_controller chip currently attempts to operate > on all CPUs/VPs in the system when masking or unmasking an interrupt. > This has a few drawbacks: > > - In multi-cluster systems we may not always have access to all CPUs in > the system. When all CPUs in a cluster are powered down that > cluster's GIC may also power down, in which case we cannot configure > its state. > > - Relatedly, if we power down a cluster after having configured > interrupts for CPUs within it then the cluster's GIC may lose state & > we need to reconfigure it. The current approach doesn't take this > into account. > > - It's wasteful if we run Linux on fewer VPs than are present in the > system. For example if we run a uniprocessor kernel on CPU0 of a > system with 16 CPUs then there's no point in us configuring CPUs > 1-15. > > - The implementation is also lacking in that it expects the range > 0..gic_vpes-1 to represent valid Linux CPU numbers which may not > always be the case - for example if we run on a system with more VPs > than the kernel is configured to support. > > Fix all of these issues by only configuring the affected interrupts for > CPUs which are online at the time, and recording the configuration in a > new struct gic_all_vpes_chip_data for later use by CPUs being brought > online. We register a CPU hotplug state (reusing > CPUHP_AP_IRQ_GIC_STARTING which the ARM GIC driver uses, and which seems > suitably generic for reuse with the MIPS GIC) and execute > irq_cpu_online() in order to configure the interrupts on the newly > onlined CPU. > > Signed-off-by: Paul Burton <paul.burton@xxxxxxxx> > Cc: Jason Cooper <jason@xxxxxxxxxxxxxx> > Cc: Marc Zyngier <marc.zyngier@xxxxxxx> > Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx> > Cc: linux-mips@xxxxxxxxxxxxxx > --- > > drivers/irqchip/irq-mips-gic.c | 72 ++++++++++++++++++++++++++++++++---------- > 1 file changed, 56 insertions(+), 16 deletions(-) > > diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c > index 6fdcc1552fab..dd9da773db90 100644 > --- a/drivers/irqchip/irq-mips-gic.c > +++ b/drivers/irqchip/irq-mips-gic.c [...] > @@ -622,6 +653,13 @@ static const struct irq_domain_ops gic_ipi_domain_ops = { > .match = gic_ipi_domain_match, > }; > > +static int gic_cpu_startup(unsigned int cpu) > +{ > + /* Invoke irq_cpu_online callbacks to enable desired interrupts */ > + irq_cpu_online(); > + > + return 0; > +} > > static int __init gic_of_init(struct device_node *node, > struct device_node *parent) > @@ -768,6 +806,8 @@ static int __init gic_of_init(struct device_node *node, > } > } > > - return 0; > + return cpuhp_setup_state(CPUHP_AP_IRQ_GIC_STARTING, > + "irqchip/mips/gic:starting", > + gic_cpu_startup, NULL); I'm wondering about this. CPUHP_AP_IRQ_GIC_STARTING is a symbol that is used on ARM platforms. You're very welcome to use it (as long as nobody builds a system with both an ARM GIC and a MIPS GIC...), but I'm a bit worried that we could end-up breaking things if one of us decides to reorder it in enum cpuhp_state. The safest option would be for you to add your own state value, which would allow the two architecture to evolve independently. Thoughts? M. -- Jazz is not dead. It just smells funny.