Repository navigation
sched/signal: Run a synchronous signal handler out of the critical section. - #20640
Merged
Merged
Conversation
…ction. nxsig_queue_action() runs the signal handler at once when the signal is for the calling thread. It is called from nxsig_tcbdispatch(), which holds the critical section. In a kernel build this happens at the end of each system call with a pending signal: the user handler then runs in user mode with interrupts disabled, and on SMP its thread holds the global critical section lock until the handler returns. The other CPUs wait for the lock all that time, and the CPU of the handler takes no interrupt. Let nxsig_queue_action() only mark the delivery, and deliver in nxsig_tcbdispatch() after it leaves the critical section. A signal that an interrupt queues meanwhile is delivered in the same loop. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
xiaoxiang781216
approved these changes
Oct 13, 2026
|
🔗 Cross-repo PR dependenciesThe read-only Build run reported the following dependent PR(s) and fetched head SHA(s):
CI run: https://github.com/apache/nuttx/actions/runs/38593989522 |
acassis
approved these changes
Oct 15, 2026
This was referenced Oct 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When a signal with a handler is for the calling thread,
nxsig_queue_action()runs the handler at once. It is called fromnxsig_tcbdispatch(), which holds the critical section. So the handler runs with interrupts disabled, and on SMP its thread holds the global critical section lock until the handler returns.In a protected or kernel build this happens at the end of each system call that leaves a pending signal unmasked: the user handler runs in user mode with interrupts disabled. Its CPU takes no interrupt, and the other CPUs wait for the critical section lock until the handler returns.
This PR lets
nxsig_queue_action()only mark the delivery.nxsig_tcbdispatch()delivers after it leaves the critical section. A signal that an interrupt queues meanwhile is delivered in the same loop.Impact
A handler that runs at once for the calling thread now runs with interrupts enabled and without the critical section. It still runs before
nxsig_tcbdispatch()returns, soraise()andkill()of the calling thread behave as before.Not changed here:
nxsig_unmask_pendingsignal()holdssched_lock()while it dispatches, so such a handler still runs with preemption disabled.Testing
qemu-armv8a:knsh, 1 CPU, withCONFIG_SCHED_IRQMONITOR=y. A test program blocks SIGUSR1, sends it to itself and unblocks it, so the handler runs at the end ofsigprocmask(). The handler spins for about 50 ms and reads/proc/irqsbefore and after (a read returns the interrupts since the last read). Over 100 handlers:ostestexits with status 0 onqemu-armv8a:knshand onqemu-armv8a:nsh(flat build). Build:lm3s6965-ek:qemu-flat, no warnings.