From 474a540f29855be019487287c819128f1e8ecb7c Mon Sep 17 00:00:00 2001 From: Major chen Date: Tue, 6 Dec 2022 15:37:09 +0800 Subject: [PATCH] ANDROID: irq: put irq_resolve_mapping under protection of __irq_enter_raw With commit a879ad2ff027 ("ANDROID: genirq: Allow an interrupt to be marked as 'raw'"), irq_resolve_mapping was moved out of scope between irq_enter() and irq_exit(). This result in handle_domain_irq-> irq_resolve_mapping->__irq_resolve_mapping->rcu_read_unlock-> __rcu_read_unlock->rcu_read_unlock_special->in_irq() return false. Now one RCU stall issue was observed due to IPI_IRQ_WORK irq storm. IPI_IRQ_WORK irq was triggered from handle_domain_irq->...-> rcu_read_unlock_special->irq_work_queue_on again and again unexpectedly due to in_irq() return false even it is in IRQ context. This patch fix its side effect without reverting commit a879ad2ff027. During call path "handle_domain_irq->irq_resolve_mapping->...-> rcu_read_unlock_special()" with use_softirq is true. 1)before this patch, in_irq() is false This will result in IPI_IRQ_WORK irq storm due to next IPI_IRQ_WORK irq will be triggered under IRQ context again and again. 2)after this patch,in_irq() will be true RCU_SOFTIRQ will be raised(but not next IPI_IRQ_WORK irq) under IRQ context. Bug: 261364180 Fixes: a879ad2ff027 ("ANDROID: genirq: Allow an interrupt to be marked as 'raw'") Change-Id: I447e5718694ebfaa11bfe4ef620d85646d5b49d6 Signed-off-by: Major chen Signed-off-by: Euiyoul Ryu --- kernel/irq/irqdesc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index f4ac5bf3ef17..a7ac8c4a9411 100644 --- a/kernel/irq/irqdesc.c +++ b/kernel/irq/irqdesc.c @@ -694,8 +694,10 @@ int handle_domain_irq(struct irq_domain *domain, int ret = 0; + __irq_enter_raw(); /* The irqdomain code provides boundary checks */ desc = irq_resolve_mapping(domain, hwirq); + __irq_exit_raw(); if (likely(desc)) { if (IS_ENABLED(CONFIG_ARCH_WANTS_IRQ_RAW) && unlikely(irq_settings_is_raw(desc))) {