From: Marc Zyngier <maz@kernel.org> To: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Cc: Will Deacon <will@kernel.org>, Catalin Marinas <catalin.marinas@arm.com>, Russell King <linux@arm.linux.org.uk>, Thomas Gleixner <tglx@linutronix.de>, Jason Cooper <jason@lakedaemon.net>, Sumit Garg <sumit.garg@linaro.org>, kernel-team@android.com Subject: [PATCH 03/11] arm64: Allow IPIs to be handled as normal interrupts Date: Tue, 19 May 2020 17:17:47 +0100 [thread overview] Message-ID: <20200519161755.209565-4-maz@kernel.org> (raw) In-Reply-To: <20200519161755.209565-1-maz@kernel.org> In order to deal with IPIs as normal interrupts, let's add a new way to register them with the architecture code. set_smp_ipi_range() takes a range of interrupts, and allows the arch code to request them as if the were normal interrupts. A standard handler is then called by the core IRQ code to deal with the IPI. This means that we don't need to call irq_enter/irq_exit, and that we don't need to deal with set_irq_regs either. So let's move the dispatcher into its own function, and leave handle_IPI() as a compatibility function. On the sending side, let's make use of ipi_send_mask, which already exists for this purpose. Signed-off-by: Marc Zyngier <maz@kernel.org> --- arch/arm64/Kconfig | 1 + arch/arm64/include/asm/smp.h | 5 ++ arch/arm64/kernel/smp.c | 92 +++++++++++++++++++++++++++++++----- 3 files changed, 86 insertions(+), 12 deletions(-) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 5d513f461957..6a6271281016 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -99,6 +99,7 @@ config ARM64 select GENERIC_CPU_VULNERABILITIES select GENERIC_EARLY_IOREMAP select GENERIC_IDLE_POLL_SETUP + select GENERIC_IRQ_IPI select GENERIC_IRQ_MULTI_HANDLER select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h index 40d5ba029615..42f366ba88bf 100644 --- a/arch/arm64/include/asm/smp.h +++ b/arch/arm64/include/asm/smp.h @@ -82,6 +82,11 @@ extern void set_smp_cross_call(void (*)(const struct cpumask *, unsigned int)); extern void (*__smp_cross_call)(const struct cpumask *, unsigned int); +/* + * Register IPI interrupts with the arch SMP code + */ +extern void set_smp_ipi_range(int ipi_base, int nr_ipi); + /* * Called from the secondary holding pen, this is the secondary CPU entry point. */ diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 061f60fe452f..93ba0025e7b9 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -67,6 +67,13 @@ struct secondary_data secondary_data; /* Number of CPUs which aren't online, but looping in kernel text. */ int cpus_stuck_in_kernel; +static int ipi_irq_base; +static int nr_ipi = NR_IPI; +static struct irq_desc *ipi_desc[NR_IPI]; + +static void ipi_setup(int cpu); +static void ipi_teardown(int cpu); + enum ipi_msg_type { IPI_RESCHEDULE, IPI_CALL_FUNC, @@ -247,6 +254,8 @@ asmlinkage notrace void secondary_start_kernel(void) */ notify_cpu_starting(cpu); + ipi_setup(cpu); + store_cpu_topology(cpu); numa_add_cpu(cpu); @@ -374,6 +383,8 @@ void cpu_die(void) local_daif_mask(); + ipi_teardown(cpu); + /* Tell __cpu_die() that this CPU is now safe to dispose of */ (void)cpu_report_death(); @@ -900,10 +911,9 @@ static void ipi_cpu_crash_stop(unsigned int cpu, struct pt_regs *regs) /* * Main handler for inter-processor interrupts */ -void handle_IPI(int ipinr, struct pt_regs *regs) +static void do_handle_IPI(int ipinr) { unsigned int cpu = smp_processor_id(); - struct pt_regs *old_regs = set_irq_regs(regs); if ((unsigned)ipinr < NR_IPI) { trace_ipi_entry_rcuidle(ipi_types[ipinr]); @@ -916,21 +926,16 @@ void handle_IPI(int ipinr, struct pt_regs *regs) break; case IPI_CALL_FUNC: - irq_enter(); generic_smp_call_function_interrupt(); - irq_exit(); break; case IPI_CPU_STOP: - irq_enter(); local_cpu_stop(); - irq_exit(); break; case IPI_CPU_CRASH_STOP: if (IS_ENABLED(CONFIG_KEXEC_CORE)) { - irq_enter(); - ipi_cpu_crash_stop(cpu, regs); + ipi_cpu_crash_stop(cpu, get_irq_regs()); unreachable(); } @@ -938,17 +943,13 @@ void handle_IPI(int ipinr, struct pt_regs *regs) #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST case IPI_TIMER: - irq_enter(); tick_receive_broadcast(); - irq_exit(); break; #endif #ifdef CONFIG_IRQ_WORK case IPI_IRQ_WORK: - irq_enter(); irq_work_run(); - irq_exit(); break; #endif @@ -967,9 +968,76 @@ void handle_IPI(int ipinr, struct pt_regs *regs) if ((unsigned)ipinr < NR_IPI) trace_ipi_exit_rcuidle(ipi_types[ipinr]); +} + +/* Legacy version, should go away once all irqchips have been converted */ +void handle_IPI(int ipinr, struct pt_regs *regs) +{ + struct pt_regs *old_regs = set_irq_regs(regs); + + irq_enter(); + do_handle_IPI(ipinr); + irq_exit(); + set_irq_regs(old_regs); } +static irqreturn_t ipi_handler(int irq, void *data) +{ + do_handle_IPI(irq - ipi_irq_base); + return IRQ_HANDLED; +} + +static void ipi_send(const struct cpumask *target, unsigned int ipi) +{ + __ipi_send_mask(ipi_desc[ipi], target); +} + +static void ipi_setup(int cpu) +{ + if (ipi_irq_base) { + int i; + + for (i = 0; i < nr_ipi; i++) + enable_percpu_irq(ipi_irq_base + i, 0); + } +} + +static void ipi_teardown(int cpu) +{ + if (ipi_irq_base) { + int i; + + for (i = 0; i < nr_ipi; i++) + disable_percpu_irq(ipi_irq_base + i); + } +} + +void __init set_smp_ipi_range(int ipi_base, int n) +{ + int i; + + WARN_ON(n < NR_IPI); + nr_ipi = min(n, NR_IPI); + + for (i = 0; i < nr_ipi; i++) { + int err; + + err = request_percpu_irq(ipi_base + i, ipi_handler, + "IPI", &irq_stat); + WARN_ON(err); + + ipi_desc[i] = irq_to_desc(ipi_base + i); + irq_set_status_flags(ipi_base + i, IRQ_NO_ACCOUNTING); + } + + ipi_irq_base = ipi_base; + __smp_cross_call = ipi_send; + + /* Setup the boot CPU immediately */ + ipi_setup(smp_processor_id()); +} + void smp_send_reschedule(int cpu) { smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE); -- 2.26.2
WARNING: multiple messages have this Message-ID (diff)
From: Marc Zyngier <maz@kernel.org> To: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Cc: Sumit Garg <sumit.garg@linaro.org>, kernel-team@android.com, Russell King <linux@arm.linux.org.uk>, Jason Cooper <jason@lakedaemon.net>, Catalin Marinas <catalin.marinas@arm.com>, Thomas Gleixner <tglx@linutronix.de>, Will Deacon <will@kernel.org> Subject: [PATCH 03/11] arm64: Allow IPIs to be handled as normal interrupts Date: Tue, 19 May 2020 17:17:47 +0100 [thread overview] Message-ID: <20200519161755.209565-4-maz@kernel.org> (raw) In-Reply-To: <20200519161755.209565-1-maz@kernel.org> In order to deal with IPIs as normal interrupts, let's add a new way to register them with the architecture code. set_smp_ipi_range() takes a range of interrupts, and allows the arch code to request them as if the were normal interrupts. A standard handler is then called by the core IRQ code to deal with the IPI. This means that we don't need to call irq_enter/irq_exit, and that we don't need to deal with set_irq_regs either. So let's move the dispatcher into its own function, and leave handle_IPI() as a compatibility function. On the sending side, let's make use of ipi_send_mask, which already exists for this purpose. Signed-off-by: Marc Zyngier <maz@kernel.org> --- arch/arm64/Kconfig | 1 + arch/arm64/include/asm/smp.h | 5 ++ arch/arm64/kernel/smp.c | 92 +++++++++++++++++++++++++++++++----- 3 files changed, 86 insertions(+), 12 deletions(-) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 5d513f461957..6a6271281016 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -99,6 +99,7 @@ config ARM64 select GENERIC_CPU_VULNERABILITIES select GENERIC_EARLY_IOREMAP select GENERIC_IDLE_POLL_SETUP + select GENERIC_IRQ_IPI select GENERIC_IRQ_MULTI_HANDLER select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h index 40d5ba029615..42f366ba88bf 100644 --- a/arch/arm64/include/asm/smp.h +++ b/arch/arm64/include/asm/smp.h @@ -82,6 +82,11 @@ extern void set_smp_cross_call(void (*)(const struct cpumask *, unsigned int)); extern void (*__smp_cross_call)(const struct cpumask *, unsigned int); +/* + * Register IPI interrupts with the arch SMP code + */ +extern void set_smp_ipi_range(int ipi_base, int nr_ipi); + /* * Called from the secondary holding pen, this is the secondary CPU entry point. */ diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 061f60fe452f..93ba0025e7b9 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -67,6 +67,13 @@ struct secondary_data secondary_data; /* Number of CPUs which aren't online, but looping in kernel text. */ int cpus_stuck_in_kernel; +static int ipi_irq_base; +static int nr_ipi = NR_IPI; +static struct irq_desc *ipi_desc[NR_IPI]; + +static void ipi_setup(int cpu); +static void ipi_teardown(int cpu); + enum ipi_msg_type { IPI_RESCHEDULE, IPI_CALL_FUNC, @@ -247,6 +254,8 @@ asmlinkage notrace void secondary_start_kernel(void) */ notify_cpu_starting(cpu); + ipi_setup(cpu); + store_cpu_topology(cpu); numa_add_cpu(cpu); @@ -374,6 +383,8 @@ void cpu_die(void) local_daif_mask(); + ipi_teardown(cpu); + /* Tell __cpu_die() that this CPU is now safe to dispose of */ (void)cpu_report_death(); @@ -900,10 +911,9 @@ static void ipi_cpu_crash_stop(unsigned int cpu, struct pt_regs *regs) /* * Main handler for inter-processor interrupts */ -void handle_IPI(int ipinr, struct pt_regs *regs) +static void do_handle_IPI(int ipinr) { unsigned int cpu = smp_processor_id(); - struct pt_regs *old_regs = set_irq_regs(regs); if ((unsigned)ipinr < NR_IPI) { trace_ipi_entry_rcuidle(ipi_types[ipinr]); @@ -916,21 +926,16 @@ void handle_IPI(int ipinr, struct pt_regs *regs) break; case IPI_CALL_FUNC: - irq_enter(); generic_smp_call_function_interrupt(); - irq_exit(); break; case IPI_CPU_STOP: - irq_enter(); local_cpu_stop(); - irq_exit(); break; case IPI_CPU_CRASH_STOP: if (IS_ENABLED(CONFIG_KEXEC_CORE)) { - irq_enter(); - ipi_cpu_crash_stop(cpu, regs); + ipi_cpu_crash_stop(cpu, get_irq_regs()); unreachable(); } @@ -938,17 +943,13 @@ void handle_IPI(int ipinr, struct pt_regs *regs) #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST case IPI_TIMER: - irq_enter(); tick_receive_broadcast(); - irq_exit(); break; #endif #ifdef CONFIG_IRQ_WORK case IPI_IRQ_WORK: - irq_enter(); irq_work_run(); - irq_exit(); break; #endif @@ -967,9 +968,76 @@ void handle_IPI(int ipinr, struct pt_regs *regs) if ((unsigned)ipinr < NR_IPI) trace_ipi_exit_rcuidle(ipi_types[ipinr]); +} + +/* Legacy version, should go away once all irqchips have been converted */ +void handle_IPI(int ipinr, struct pt_regs *regs) +{ + struct pt_regs *old_regs = set_irq_regs(regs); + + irq_enter(); + do_handle_IPI(ipinr); + irq_exit(); + set_irq_regs(old_regs); } +static irqreturn_t ipi_handler(int irq, void *data) +{ + do_handle_IPI(irq - ipi_irq_base); + return IRQ_HANDLED; +} + +static void ipi_send(const struct cpumask *target, unsigned int ipi) +{ + __ipi_send_mask(ipi_desc[ipi], target); +} + +static void ipi_setup(int cpu) +{ + if (ipi_irq_base) { + int i; + + for (i = 0; i < nr_ipi; i++) + enable_percpu_irq(ipi_irq_base + i, 0); + } +} + +static void ipi_teardown(int cpu) +{ + if (ipi_irq_base) { + int i; + + for (i = 0; i < nr_ipi; i++) + disable_percpu_irq(ipi_irq_base + i); + } +} + +void __init set_smp_ipi_range(int ipi_base, int n) +{ + int i; + + WARN_ON(n < NR_IPI); + nr_ipi = min(n, NR_IPI); + + for (i = 0; i < nr_ipi; i++) { + int err; + + err = request_percpu_irq(ipi_base + i, ipi_handler, + "IPI", &irq_stat); + WARN_ON(err); + + ipi_desc[i] = irq_to_desc(ipi_base + i); + irq_set_status_flags(ipi_base + i, IRQ_NO_ACCOUNTING); + } + + ipi_irq_base = ipi_base; + __smp_cross_call = ipi_send; + + /* Setup the boot CPU immediately */ + ipi_setup(smp_processor_id()); +} + void smp_send_reschedule(int cpu) { smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE); -- 2.26.2 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2020-05-19 16:18 UTC|newest] Thread overview: 72+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-05-19 16:17 [PATCH 00/11] arm/arm64: Turning IPIs into normal interrupts Marc Zyngier 2020-05-19 16:17 ` Marc Zyngier 2020-05-19 16:17 ` [PATCH 01/11] genirq: Add fasteoi IPI flow Marc Zyngier 2020-05-19 16:17 ` Marc Zyngier 2020-05-19 19:47 ` Florian Fainelli 2020-05-19 19:47 ` Florian Fainelli 2020-06-12 9:54 ` Marc Zyngier 2020-06-12 9:54 ` Marc Zyngier 2020-05-19 22:25 ` Valentin Schneider 2020-05-19 22:25 ` Valentin Schneider 2020-05-19 22:29 ` Valentin Schneider 2020-05-19 22:29 ` Valentin Schneider 2020-06-12 9:58 ` Marc Zyngier 2020-06-12 9:58 ` Marc Zyngier 2020-05-19 16:17 ` [PATCH 02/11] genirq: Allow interrupts to be excluded from /proc/interrupts Marc Zyngier 2020-05-19 16:17 ` Marc Zyngier 2020-05-19 16:17 ` Marc Zyngier [this message] 2020-05-19 16:17 ` [PATCH 03/11] arm64: Allow IPIs to be handled as normal interrupts Marc Zyngier 2020-05-21 14:03 ` Valentin Schneider 2020-05-21 14:03 ` Valentin Schneider 2020-05-19 16:17 ` [PATCH 04/11] ARM: " Marc Zyngier 2020-05-19 16:17 ` Marc Zyngier 2020-05-19 22:24 ` Russell King - ARM Linux admin 2020-05-19 22:24 ` Russell King - ARM Linux admin 2020-05-21 14:03 ` Valentin Schneider 2020-05-21 14:03 ` Valentin Schneider 2020-05-21 15:12 ` Russell King - ARM Linux admin 2020-05-21 15:12 ` Russell King - ARM Linux admin 2020-05-21 16:11 ` Valentin Schneider 2020-05-21 16:11 ` Valentin Schneider 2020-05-19 16:17 ` [PATCH 05/11] irqchip/gic-v3: Describe the SGI range Marc Zyngier 2020-05-19 16:17 ` Marc Zyngier 2020-05-19 16:17 ` [PATCH 06/11] irqchip/gic-v3: Configure SGIs as standard interrupts Marc Zyngier 2020-05-19 16:17 ` Marc Zyngier 2020-05-20 9:52 ` Sumit Garg 2020-05-20 9:52 ` Sumit Garg 2020-05-20 10:24 ` Marc Zyngier 2020-05-20 10:24 ` Marc Zyngier 2020-05-21 14:04 ` Valentin Schneider 2020-05-21 14:04 ` Valentin Schneider 2020-06-12 10:39 ` Marc Zyngier 2020-06-12 10:39 ` Marc Zyngier 2020-05-19 16:17 ` [PATCH 07/11] irqchip/gic: Refactor SMP configuration Marc Zyngier 2020-05-19 16:17 ` Marc Zyngier 2020-05-19 16:17 ` [PATCH 08/11] irqchip/gic: Configure SGIs as standard interrupts Marc Zyngier 2020-05-19 16:17 ` Marc Zyngier 2021-04-20 20:37 ` dann frazier 2021-04-20 20:37 ` dann frazier 2021-04-20 21:25 ` dann frazier 2021-04-20 21:25 ` dann frazier 2021-04-21 10:58 ` Marc Zyngier 2021-04-21 10:58 ` Marc Zyngier 2021-04-21 14:52 ` dann frazier 2021-04-21 14:52 ` dann frazier 2021-04-21 15:49 ` Marc Zyngier 2021-04-21 15:49 ` Marc Zyngier 2020-05-19 16:17 ` [PATCH 09/11] irqchip/gic-common: Don't enable SGIs by default Marc Zyngier 2020-05-19 16:17 ` Marc Zyngier 2020-05-19 16:17 ` [PATCH 10/11] irqchip/bcm2836: Configure mailbox interrupts as standard interrupts Marc Zyngier 2020-05-19 16:17 ` Marc Zyngier 2020-05-19 16:17 ` [PATCH 11/11] arm64: Kill __smp_cross_call and co Marc Zyngier 2020-05-19 16:17 ` Marc Zyngier 2020-05-19 17:50 ` [PATCH 00/11] arm/arm64: Turning IPIs into normal interrupts Florian Fainelli 2020-05-19 17:50 ` Florian Fainelli 2020-05-19 19:47 ` Florian Fainelli 2020-05-19 19:47 ` Florian Fainelli 2020-06-12 9:49 ` Marc Zyngier 2020-06-12 9:49 ` Marc Zyngier 2020-06-12 16:57 ` Florian Fainelli 2020-06-12 16:57 ` Florian Fainelli 2020-05-19 22:25 ` Valentin Schneider 2020-05-19 22:25 ` Valentin Schneider
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20200519161755.209565-4-maz@kernel.org \ --to=maz@kernel.org \ --cc=catalin.marinas@arm.com \ --cc=jason@lakedaemon.net \ --cc=kernel-team@android.com \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux@arm.linux.org.uk \ --cc=sumit.garg@linaro.org \ --cc=tglx@linutronix.de \ --cc=will@kernel.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.