summaryrefslogtreecommitdiff
path: root/include/linux/irqchip
diff options
context:
space:
mode:
authorValentin Schneider <valentin.schneider@arm.com>2021-10-27 16:15:05 +0100
committerMarc Zyngier <maz@kernel.org>2021-12-16 13:21:11 +0000
commitd23bc2bc1d634658d7fa96395419c1c553a784f0 (patch)
tree13a8bb0cde87464cd7fd852bc63d2da7899d098e /include/linux/irqchip
parentc0cdc89072a3e1ae3981437f385de14b7bba8fd8 (diff)
irqchip/gic-v3-its: Postpone LPI pending table freeing and memreserve
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: Valentin Schneider <valentin.schneider@arm.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20211027151506.2085066-3-valentin.schneider@arm.com
Diffstat (limited to 'include/linux/irqchip')
-rw-r--r--include/linux/irqchip/arm-gic-v3.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index 0dc34d7d735a..51b85506ae90 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -632,6 +632,7 @@ struct rdists {
struct irq_domain;
struct fwnode_handle;
+int __init its_lpi_memreserve_init(void);
int its_cpu_init(void);
int its_init(struct fwnode_handle *handle, struct rdists *rdists,
struct irq_domain *domain);