[PATCH] irqchip/ast2700-intc: Avoid allocating in the irq_domain activate callback

Ryan Chen <[email protected]>
Newsgroups org.ozlabs.lists.linux-aspeed,org.infradead.lists.linux-arm-kernel,org.infradead.lists.linux-riscv,org.kernel.vger.linux-kernel
Message-ID <20260819-fix-ast2700-intc-atomic-alloc-v1-1-d92a02e2a239@aspeedtech.com>
The IRQ core calls the irq_domain .activate callback from __setup_irq()
with desc->lock held and interrupts disabled. Both
aspeed_intc1_irq_domain_activate() and the aspeed_intc0_resolve_route()
it invokes test a compatible string with fwnode_device_is_compatible(),
which wraps fwnode_property_match_string() and allocates with GFP_KERNEL.

Besides sleeping in atomic context, that makes the irq_desc lock depend
on fs_reclaim, which lockdep reports as an inversion because
irq_desc_lock_class is also taken in hardirq context:

  WARNING: possible irq lock inversion dependency detected
  swapper/0/0 just changed the state of lock:
  (&irq_desc_lock_class){-...}-{2:2}, at: handle_level_irq+0x28/0x168
  but this lock took another, HARDIRQ-unsafe lock in the past:
   (fs_reclaim){+.+.}-{0:0}
  ...
    fs_reclaim_acquire
    __kmalloc_noprof
    fwnode_property_match_string
    aspeed_intc0_resolve_route
    aspeed_intc1_irq_domain_activate

Both call sites are only ever handed OF nodes, so use
of_device_is_compatible() instead: it walks the property in place and
does not allocate.

Fixes: 07825e41519a ("irqchip/ast2700-intc: Add AST2700-A2 support")
Reported-by: Andrew Jeffery <[email protected]>
Signed-off-by: Ryan Chen <[email protected]>
Tested-by: Andrew Jeffery <[email protected]>
---
Tested on an AST2700 EVB with CONFIG_PROVE_LOCKING=y: the irq lock
inversion splat quoted in the patch is gone, and the ast2700-intc0 KUnit
suite still passes 9/9.
---
 drivers/irqchip/irq-ast2700-intc0.c | 2 +-
 drivers/irqchip/irq-ast2700-intc1.c | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-ast2700-intc0.c b/drivers/irqchip/irq-ast2700-intc0.c
index 14b8b88f1179..c85b98a19bd4 100644
--- a/drivers/irqchip/irq-ast2700-intc0.c
+++ b/drivers/irqchip/irq-ast2700-intc0.c
@@ -312,7 +312,7 @@ int aspeed_intc0_resolve_route(const struct irq_domain *c0domain, size_t nc1outs
 		return -ENOENT;
 
 	if (!IS_ENABLED(CONFIG_ASPEED_AST2700_INTC_TEST) &&
-	    !fwnode_device_is_compatible(c0domain->fwnode, "aspeed,ast2700-intc0"))
+	    !of_device_is_compatible(to_of_node(c0domain->fwnode), "aspeed,ast2700-intc0"))
 		return -ENODEV;
 
 	intc0 = c0domain->host_data;
diff --git a/drivers/irqchip/irq-ast2700-intc1.c b/drivers/irqchip/irq-ast2700-intc1.c
index 59e8f0d5ddcd..df6acbafce2d 100644
--- a/drivers/irqchip/irq-ast2700-intc1.c
+++ b/drivers/irqchip/irq-ast2700-intc1.c
@@ -157,7 +157,8 @@ static int aspeed_intc1_irq_domain_activate(struct irq_domain *domain,
 					intc1->ranges.nranges,
 					intc1->ranges.ranges, &resolved);
 	if (rc < 0) {
-		if (!fwnode_device_is_compatible(intc1->upstream->fwnode, "riscv,aplic")) {
+		if (!of_device_is_compatible(to_of_node(intc1->upstream->fwnode),
+					     "riscv,aplic")) {
 			dev_warn(intc1->dev,
 				 "Failed to resolve interrupt route for hwirq %lu in domain %s\n",
 				 data->hwirq, domain->name);

---
base-commit: 4477a78374a57c3809b172ad30cceabda48c47c6
change-id: 20260819-fix-ast2700-intc-atomic-alloc-93248a29a1c0

Best regards,
-- 
Ryan Chen <[email protected]>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.