bcm27xx: update 6.1 patches to latest version
[openwrt/openwrt.git] / target / linux / bcm27xx / patches-6.1 / 950-0833-drivers-irqchip-irq-bcm2835-Concurrency-fix.patch
1 From e804bd1843236a63815e9acfb1a38ebf9a28ef5b Mon Sep 17 00:00:00 2001
2 From: Phil Elwell <phil@raspberrypi.com>
3 Date: Thu, 31 Aug 2023 16:45:44 +0100
4 Subject: [PATCH] drivers: irqchip: irq-bcm2835: Concurrency fix
5
6 The commit shown in Fixes: aims to improve interrupt throughput by
7 getting the handlers invoked on different CPU cores. It does so (*) by
8 using an irq_ack hook to change the interrupt routing.
9
10 Unfortunately, the IRQ status bits must be cleared at source, which only
11 happens once the interrupt handler has run - there is no easy way for
12 one core to claim one of the IRQs before sending the remainder to the
13 next core on the list, so waking another core immediately results in a
14 race with a chance of both cores handling the same IRQ. It is probably
15 for this reason that the routing change is deferred to irq_ack, but that
16 doesn't guarantee no clashes - after irq_ack is called, control returns
17 to bcm2836_chained_handler_irq which proceeds to check for other pending
18 IRQs at a time when the next core is probably doing the same thing.
19
20 Since the whole point of the original commit is to distribute the IRQ
21 handling, there is no reason to attempt to handle multiple IRQs in one
22 interrupt callback, so the problem can be solved (or at least made much
23 harder to reproduce) by changing a "while" into an "if", so that each
24 invocation only handles one IRQ.
25
26 (*) I'm not convinced it's as effective as claimed since irq_ack is
27 called _after_ the interrupt handler, but the author thought it made a
28 difference.
29
30 See: https://github.com/raspberrypi/linux/issues/5214
31 https://github.com/raspberrypi/linux/pull/1794
32
33 Fixes: fd4c9785bde8 ("ARM64: Round-Robin dispatch IRQs between CPUs.")
34 Signed-off-by: Phil Elwell <phil@raspberrypi.com>
35 ---
36 drivers/irqchip/irq-bcm2835.c | 3 ++-
37 1 file changed, 2 insertions(+), 1 deletion(-)
38
39 --- a/drivers/irqchip/irq-bcm2835.c
40 +++ b/drivers/irqchip/irq-bcm2835.c
41 @@ -343,7 +343,8 @@ static void bcm2836_chained_handle_irq(s
42 {
43 u32 hwirq;
44
45 - while ((hwirq = get_next_armctrl_hwirq()) != ~0)
46 + hwirq = get_next_armctrl_hwirq();
47 + if (hwirq != ~0)
48 generic_handle_domain_irq(intc.domain, hwirq);
49 }
50