powerpc/powernv: Bump opal_init initcall priority

Michael Ellerman mpe at ellerman.id.au
Mon Jun 15 17:13:09 AEST 2015


On Mon, 2015-06-15 at 13:44 +1000, Alistair Popple wrote:
> On Fri, 12 Jun 2015 19:47:35 Michael Ellerman wrote:
> > On Thu, 2015-11-06 at 09:25:29 UTC, Alistair Popple wrote:
> > > opal_init() is called via a machine_subsys_initcall(). Due to a hack
> > > in the eeh code the eeh driver is initialised with at the same
> > > initcall level. This means depending on link ordering the following
> > > error can occur because the opal irchip has not been initialised:
> > > 
> > > irq: XICS didn't like hwirq-0x9 to VIRQ17 mapping (rc=-22)
> > > pnv_eeh_post_init: Can't request OPAL event interrupt (0)
> > > 
> > > This patch solves the issue by making sure opal_init is called prior
> > > to the subsystems that may need it.
> > 
> > What is the hack in the eeh code?
> > 
> > I'm seeing eeh_ops->post_init() called from eeh_init() which is
> > core_initcall_sync(), is that what you're talking about?
> 
> Yes, but there is this at the start of eeh_init():
> 
> 	/*
> 	 * We have to delay the initialization on PowerNV after
> 	 * the PCI hierarchy tree has been built because the PEs
> 	 * are figured out based on PCI devices instead of device
> 	 * tree nodes
> 	 */
> 	if (machine_is(powernv) && cnt++ <= 0)
> 		return ret;
> 
> Which basically stops eeh_init() running from the core initcall level on 
> PowerNV. Instead on PowerNV eeh_init() gets called from pnv_pci_ioda_fixup() 
> which itself is called via the PCI layer from a subsys_initcall (ie. the same 
> level as opal_init() is called at without this patch). This is why I missed 
> this during my testing - apparently I got lucky during my compilations and 
> opal_init() must have been called prior to the pci subsystem initialisation.
> 
> Ideally I'd like to change the way eeh_init() is called and make it an 
> explicit call for each machine type, however that is a more invasive change 
> which will take some time as there seem to be a bunch of subtle dependencies 
> between initcalls for different platforms that aren't well documented and I'm 
> not convinced I understand them all yet. Hence this "quick" fix.

Yeah right, that's pretty gross. I don't grok why EEH needs to run as early as
it does, but there's probably a reason.

> > Regardless of which level it needs to be at, the only thing that needs to 
> run
> > early is opal_event_init() am I right? Not all of opal_init().
> 
> Yes, that is correct. But I was trying to avoid doing the thing which seemed 
> to have got us in this mess in the first place (ie. just making everything 
> that needs to run "early" run from a core_initcall). However I guess just 
> running opal_event_init() earlier is less likely to have unintended side 
> effects than running all of opal_init() earlier. Let me know what you'd 
> prefer.

Moving opal_event_init() earlier seems like the safest fix. It should only need
to be arch_initcall which is reasonable.


It might also be worth something like this for safety:

diff --git a/arch/powerpc/platforms/powernv/opal-irqchip.c b/arch/powerpc/platforms/powernv/opal-irqchip.c
index 841135f48981..c40e424fcde2 100644
--- a/arch/powerpc/platforms/powernv/opal-irqchip.c
+++ b/arch/powerpc/platforms/powernv/opal-irqchip.c
@@ -244,6 +244,9 @@ out:
  */
 int opal_event_request(unsigned int opal_event_nr)
 {
+       if (WARN_ON_ONCE(!opal_event_irqchip.domain))
+               return NO_IRQ;
+
        return irq_create_mapping(opal_event_irqchip.domain, opal_event_nr);
 }
 EXPORT_SYMBOL(opal_event_request);



cheers




More information about the Linuxppc-dev mailing list