• Paul Mackerras's avatar
    powerpc/powernv: Don't call generic code on offline cpus · d6a4f709
    Paul Mackerras authored
    On PowerNV platforms, when a CPU is offline, we put it into nap mode.
    It's possible that the CPU wakes up from nap mode while it is still
    offline due to a stray IPI.  A misdirected device interrupt could also
    potentially cause it to wake up.  In that circumstance, we need to clear
    the interrupt so that the CPU can go back to nap mode.
    
    In the past the clearing of the interrupt was accomplished by briefly
    enabling interrupts and allowing the normal interrupt handling code
    (do_IRQ() etc.) to handle the interrupt.  This has the problem that
    this code calls irq_enter() and irq_exit(), which call functions such
    as account_system_vtime() which use RCU internally.  Use of RCU is not
    permitted on offline CPUs and will trigger errors if RCU checking is
    enabled.
    
    To avoid calling into any generic code which might use RCU, we adopt
    a different method of clearing interrupts on offline CPUs.  Since we
    are on the PowerNV platform, we know that the system interrupt
    controller is a XICS being driven directly (i.e. not via hcalls) by
    the kernel.  Hence this adds a new icp_native_flush_interrupt()
    function to the native-mode XICS driver and arranges to call that
    when an offline CPU is woken from nap.  This new function reads the
    interrupt from the XICS.  If it is an IPI, it clears the IPI; if it
    is a device interrupt, it prints a warning and disables the source.
    Then it does the end-of-interrupt processing for the interrupt.
    
    The other thing that briefly enabling interrupts did was to check and
    clear the irq_happened flag in this CPU's PACA.  Therefore, after
    flushing the interrupt from the XICS, we also clear all bits except
    the PACA_IRQ_HARD_DIS (interrupts are hard disabled) bit from the
    irq_happened flag.  The PACA_IRQ_HARD_DIS flag is set by power7_nap()
    and is left set to indicate that interrupts are hard disabled.  This
    means we then have to ignore that flag in power7_nap(), which is
    reasonable since it doesn't indicate that any interrupt event needs
    servicing.
    Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
    Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
    d6a4f709
smp.c 5.36 KB