• Valentin Schneider's avatar
    irqchip/gic-v3-its: Postpone LPI pending table freeing and memreserve · d23bc2bc
    Valentin Schneider authored
    Memory used by the LPI tables have to be made persistent for kexec to have
    a chance to work, as explained in [1]. If they have been made persistent
    and we are booting into a kexec'd kernel, we also need to free the pages
    that were preemptively allocated by the new kernel for those tables.
    
    Both of those operations currently happen during its_cpu_init(), which
    happens in a _STARTING (IOW atomic) cpuhp callback for secondary
    CPUs. efi_mem_reserve_iomem() issues a GFP_ATOMIC allocation, which
    unfortunately doesn't work under PREEMPT_RT (this ends up grabbing a
    non-raw spinlock, which can sleep under PREEMPT_RT). Similarly, freeing the
    pages ends up grabbing a sleepable spinlock.
    
    Since the memreserve is only required by kexec, it doesn't have to be done
    so early in the secondary boot process. Issue the reservation in a new
    CPUHP_AP_ONLINE_DYN cpuhp callback, and piggy-back the page freeing on top
    of it. A CPU gets to run the body of this new callback exactly once.
    
    As kexec issues a machine_shutdown() prior to machine_kexec(), it will be
    serialized vs a CPU being plugged to life by the hotplug machinery - either
    the CPU will have been brought up and have had its redistributor's pending
    table memreserved, or it never went online and will have its table
    allocated by the new kernel.
    
    [1]: https://lore.kernel.org/lkml/20180921195954.21574-1-marc.zyngier@arm.com/Signed-off-by: default avatarValentin Schneider <valentin.schneider@arm.com>
    Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
    Link: https://lore.kernel.org/r/20211027151506.2085066-3-valentin.schneider@arm.com
    d23bc2bc
irq-gic-v3.c 57.5 KB