Re: Spurious task resume due to SIGSHADOW

Richard Weinberger <[email protected]>
Newsgroups dev.linux.lists.xenomai
Message-ID <CAFLxGvyUZWXEYdvKynRhJEkJGnEKomCmKYvZg3+Z7DJUM+SUPQ@mail.gmail.com>
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.

> > - 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.
-- 
Thanks,
//richard
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.