From 629dff91e3c7225f2599668aec8e3edf197538d0 Mon Sep 17 00:00:00 2001 From: yushuailong Date: Mon, 14 Sep 2026 20:16:27 +0800 Subject: [PATCH] sched/irq: Preserve all handlers when extending IRQ chains. Allocate the new handler node independently of the initial chain conversion so handlers beyond the second are appended instead of silently dropped. Delay vector conversion until both required nodes are available to avoid leaving a partially constructed chain on allocation failure. Assisted-by: OpenAI Codex Signed-off-by: yushuailong --- sched/irq/irq_chain.c | 61 +++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/sched/irq/irq_chain.c b/sched/irq/irq_chain.c index 9b1284847de27..56d57fc70ab85 100644 --- a/sched/irq/irq_chain.c +++ b/sched/irq/irq_chain.c @@ -158,45 +158,47 @@ int irqchain_attach(int ndx, xcpt_t isr, FAR void *arg) flags = spin_lock_irqsave(&g_irqchainlock); if (isr != irq_unexpected_isr) { - if (g_irqvector[ndx].handler != irqchain_dispatch) + node = (FAR struct irqchain_s *) + sq_remfirst(&g_irqchainfreelist); + if (node == NULL) { - if (sq_count(&g_irqchainfreelist) < 2u) - { - ret = -ENOMEM; - } - else - { - node = (FAR struct irqchain_s *) - sq_remfirst(&g_irqchainfreelist); - DEBUGASSERT(node != NULL); - - node->handler = g_irqvector[ndx].handler; - node->arg = g_irqvector[ndx].arg; - node->next = NULL; - - g_irqvector[ndx].handler = irqchain_dispatch; - g_irqvector[ndx].arg = node; + ret = -ENOMEM; + } + else + { + node->handler = isr; + node->arg = arg; + node->next = NULL; - node = (FAR struct irqchain_s *) + if (g_irqvector[ndx].handler != irqchain_dispatch) + { + curr = (FAR struct irqchain_s *) sq_remfirst(&g_irqchainfreelist); - if (node == NULL) + if (curr == NULL) { + sq_addfirst((FAR struct sq_entry_s *)node, + &g_irqchainfreelist); ret = -ENOMEM; } else { - node->handler = isr; - node->arg = arg; - node->next = NULL; + curr->handler = g_irqvector[ndx].handler; + curr->arg = g_irqvector[ndx].arg; + curr->next = node; - curr = g_irqvector[ndx].arg; - while (curr->next != NULL) - { - curr = curr->next; - } - - curr->next = node; + g_irqvector[ndx].handler = irqchain_dispatch; + g_irqvector[ndx].arg = curr; + } + } + else + { + curr = g_irqvector[ndx].arg; + while (curr->next != NULL) + { + curr = curr->next; } + + curr->next = node; } } } @@ -217,6 +219,7 @@ int irqchain_detach(int irq, xcpt_t isr, FAR void *arg) FAR struct irqchain_s *curr; FAR struct irqchain_s *first; int ndx = IRQ_TO_NDX(irq); + if (ndx < 0) { ret = ndx;