Hang during smokey posix_cond test w/ cobalt and PREEMPT_RT enabled
Dominic Rath <[email protected]> Tue, 21 Jul 2026 09:21:31 +0200
| Newsgroups | dev.linux.lists.xenomai |
|---|---|
| Message-ID | <[email protected]> |
Dear Xenomai team, we're seeing a hang during the execution of the posix_cond test in smokey. When breaking into the stuck test, I can see that the main thread is waiting on a semaphore in thread_spawn, and the newly spawned thread appears to be stuck in cobalt_thread_harden, before it had a chance to post the semaphore. Apart from that single test, all other tests run successfully, and our application was running fine, too. We're using Xenomai 3.3.3 on an ARM64 running Linux kernel 6.12 with PREEMPT_RT enabled. The kernel is a heavily patched vendor tree based on v6.12.y-cip merged with v6.12.y-cip-dovetail, and I can't rule out that we've made some mistake there. When running the tests without PREEMPT_RT enabled, the tests complete successfully. Looking at some tracepoints and function traces we noticed that the newly spawned thread actually wanted to relax again, but instead the kernel is in an endless loop calling lostage_task_wakeup on the main thread. What happened is that the main thread wanted to relax, hardened again, and called xnthread_relax again. On that second relax the relax_work.inband_work was queued via irq_work_queue again, while it was already on the lazy_list, resulting in the endless loop. It seems that the main thread is continuing execution in the Linux domain after the first call to xnthread_relax without lostage_task_wakeup running first. That gives it a chance to harden and call relax the second time, where the endless loop on the lazy_list gets created. Only afterwards is irq_work_run_list executing again and calls cobalt_lostage_wakeup, eventually in an endless loop. This is possible, because relax_work.inband_work gets completely initialized on each call to xnthread_relax via IRQ_WORK_INIT. This causes the check for pending irq_work in irq_work_queue to not detect that this item was already queued. I was able to fix this by moving the initialization of thread-> relax_work.inband_work to __xnthread_init. With that changed, the test successfully completes even with PREEMPT_RT enabled. I believe the reason why this works without PREEMPT_RT, or when using IRQ_WORK_INIT_HARD (tried that, too), is that the irq_work is called immediately when the core is back in secondary mode, whereas with PREEMPT_RT it is deferred (to the next tick?). What I'm not so sure about is the following: - is running Xenomai 3 with cobalt on a kernel with PREEMPT_RT supported, i.e. should this work? - is it conceivable that the main thread continues execution in the Linux domain before lostage_task_wakeup got called? Or does this indicate that there's something else wrong with our setup? I've enabled all of the Xenomai, dovetail and PREEMPT_RT debug checks that made sense to me and I'm not getting any errors, but of course I might have missed some useful CONFIG option. Best Regards, Dominic