Re: Spurious task resume due to SIGSHADOW
Jan Kiszka <[email protected]>
| Newsgroups | dev.linux.lists.xenomai |
|---|---|
| Message-ID | <[email protected]> |
On 12.05.26 09:19, Richard Weinberger wrote: > On Tue, May 12, 2026 at 7:50 AM Jan Kiszka <[email protected]> wrote: >> >> On 11.05.26 23:49, Richard Weinberger wrote: >>> I'm currently debugging an issue on a very old Xenomai system, while >>> reading the source I noticed that the very same issue could also exist >>> on recent Xenomai releases. >>> >>> What I see is the following: >>> - A task gets suspended and unblocked using rt_task_suspend() and >>> rt_task_unblock() >> >> This is intentionally rt_task_unblock instead of rt_task_resume? > > From what I can tell, yes. > >> Because: >> >> "A nesting count is maintained so that rt_task_suspend() and >> rt_task_resume() must be used in pairs." > > The application has non-trivial thread management, from what I can > tell, it's fine. > Unlikely, because it will completely confuse tcb->suspends, preventing future suspends for the task that was not properly resumed. >>> - In some cases it happens that the task resumes to execute >>> - It resumes because a Linux signal is pending, being SIGSHADOW >>> >>> Since SIGSHADOW is internally used to suspend a task, this alerted me. >>> So, I suspect the following issue: >>> When xnthread_suspend() fires SIGSHADOW using >>> __xnthread_signal(thread, SIGSHADOW, SIGSHADOW_ACTION_HARDEN); nothing >>> seems to prevent the case where the target task enters the primary >>> domain right before it sees SIGSHADOW. In the next step >>> do_sigwake_event() causes it to resume instead of sleeping. >>> >>> Hmm? >>> >> >> Traces to confirm this theory would be good. But it could indeed be >> problematic that the target state (__THREAD_S_SUSPENDED) is only tracked >> in userspace where the scheduler has no access to while waking a task. > > I think I found a reproducer. See next patch in this mail thread. > > This quick and dirty change seems to mitigate the problem, but I consider it > a sledge hammer: > diff --git a/kernel/cobalt/dovetail/kevents.c b/kernel/cobalt/dovetail/kevents.c > index 7402e2ef6..d72c3788b 100644 > --- a/kernel/cobalt/dovetail/kevents.c > +++ b/kernel/cobalt/dovetail/kevents.c > @@ -145,6 +145,14 @@ static int handle_sigwake_event(struct task_struct *p) > if (xnthread_test_state(thread, XNRELAX)) > goto out; > > + if (sigismember(&p->pending.signal, SIGSHADOW)) > + goto out; > + > + if (sigismember(&p->signal->shared_pending.signal, SIGSHADOW)) > + goto out; > + > /* > * Allow a thread stopped for debugging to resume briefly in order to > * migrate to secondary mode. xnthread_relax will reapply XNDBGSTOP. Will have a look, thanks. Jan -- Siemens AG, Foundational Technologies Linux Expert Center