Re: The state of Xenomai 4 on Xilinx Zynq-7000 (or ARM32 in general)

Philippe Gerum <[email protected]>
Newsgroups dev.linux.lists.xenomai
Message-ID <[email protected]>
Gerte Hoogewerf <[email protected]> writes:

> Hi Jan/Philippe,
>
> Philippe wrote:
>> [..] the following patch allows the socfpga to boot, could you please try it on the Zynq?
>
> Thanks for the patch. That patch doesn't make it better or worse; it's
> an orthogonal problem and my configuration wasn't affected by it.
>
> Jan wrote:
>> That would indeed be welcome already.
>
> We will try to participate.
>
>> [..] I had to manually enable CONFIG_VDSO
>
> Noted. Thanks for the tip.
>
> With a bit of AI research, I landed on something that fixes the
> problem for me on "smp_twd" with CONFIG_SMP=y. I'll share the attached
> patch to provide further insight into the problem. It may not be the
> best candidate for direct adoption, but hopefully it'll shed some
> light on the problem.
>
> Furthermore, here's the AI's explanation:
>
>> On Zynq-7000, smp_twd.c sets CLOCK_EVT_FEAT_C3STOP on the TWD unless the DT node
>> has "always-on". With no broadcast device registered, tick_is_oneshot_available() never
>> returns true, so Linux never switches that CPU to oneshot; and tick_install_proxy() just
>> reads td->mode rather than forcing the switch, so the EVL proxy inherits periodic mode too
>> and the in-band relay never gets armed. Jiffies freeze silently until the first real timed sleep
>> hangs forever.
>
> For me, the "timed sleep" involved a network driver toggling the PHY
> reset.  It was asking the kernel for a one second delay (via
> "jiffies"), while jiffies was basically stuck. This is why our
> original boot attempts never reached userland.
>

Ok, makes sense. There is no reason for the proxy timer to inherit the
C3STOP misfeature in the first place, since we are going to use it for
high-accuracy timing, and playing stop-and-go with the timer chip is
certainly not the best way to do this. The evl core already prevents the
idle mode to enter C3STOP, but as you pointed out, we also need the
timer core to always pick oneshot mode for the proxy, which was
overlooked.

Could you try this patch, without the dts fixup, and let us know of the
outcome?

diff --git a/kernel/time/tick-proxy.c b/kernel/time/tick-proxy.c
index 5a877987a84e4..6d2b7a860d230 100644
--- a/kernel/time/tick-proxy.c
+++ b/kernel/time/tick-proxy.c
@@ -229,13 +229,16 @@ int tick_setup_proxy(struct clock_proxy_device *dev)
 
 	/*
 	 * Inherit the feature bits since the proxy device has the
-	 * same capabilities than the real one we are overriding
-	 * (including CLOCK_EVT_FEAT_C3STOP if present).
+	 * same capabilities than the real one we are overriding,
+	 * except for C3STOP which is omitted to prevent the timer
+	 * core from fully disabling oneshot mode if no
+	 * oneshot-capable broadcast device is available either.
 	 */
 	proxy_dev = &dev->proxy_device;
 	memset(proxy_dev, 0, sizeof(*proxy_dev));
-	proxy_dev->features = real_dev->features |
-		CLOCK_EVT_FEAT_PERCPU | CLOCK_EVT_FEAT_PROXY;
+	proxy_dev->features = (real_dev->features |
+			CLOCK_EVT_FEAT_PERCPU | CLOCK_EVT_FEAT_PROXY)
+		& ~CLOCK_EVT_FEAT_C3STOP;
 	proxy_dev->name = "proxy";
 	proxy_dev->irq = real_dev->irq;
 	proxy_dev->bound_on = -1;

-- 
Philippe.
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.