arch: fix the issue of asynchronous signal processing

in SMP, signal processing cannot be nested, we use xcp.sigdeliver to identify whether there is currently a signal being processed, but this state does not match the actual situation
One possible scenario is that signal processing has already been completed, but an interrupt occurs, resulting in xcp.sigdeliver not being correctly set to NULL,
At this point, a new signal arrives, which can only be placed in the queue and cannot be processed immediately
Our solution is that signal processing and signal complete status are set in the same critical section, which can ensure status synchronization

Signed-off-by: hujun5 <hujun5@xiaomi.com>
This commit is contained in:
hujun5
2023-04-26 11:19:42 +08:00
committed by Alin Jerpelea
parent 35dee8fdd2
commit 0f243bde33
10 changed files with 125 additions and 29 deletions
+12 -2
View File
@@ -84,14 +84,15 @@ void sparc_sigdeliver(void)
sparc_copystate(regs, rtcb->xcp.regs);
retry:
#ifdef CONFIG_SMP
/* In the SMP case, up_schedule_sigaction(0) will have incremented
* 'irqcount' in order to force us into a critical section. Save the
* pre-incremented irqcount.
*/
saved_irqcount = rtcb->irqcount - 1;
DEBUGASSERT(saved_irqcount >= 0);
saved_irqcount = rtcb->irqcount;
DEBUGASSERT(saved_irqcount >= 1);
/* Now we need call leave_critical_section() repeatedly to get the irqcount
* to zero, freeing all global spinlocks that enforce the critical section.
@@ -144,6 +145,12 @@ void sparc_sigdeliver(void)
set_errno(saved_errno);
if (!sq_empty(&rtcb->sigpendactionq) &&
(rtcb->flags & TCB_FLAG_SIGNAL_ACTION) == 0)
{
goto retry;
}
/* Modify the saved return state with the actual saved values in the
* TCB. This depends on the fact that nested signal handling is
* not supported. Therefore, these values will persist throughout the
@@ -195,5 +202,8 @@ void sparc_sigdeliver(void)
*/
board_autoled_off(LED_SIGNAL);
#ifdef CONFIG_SMP
rtcb->irqcount--;
#endif
sparc_fullcontextrestore(regs);
}