> This is, ultimately, the problem.  You can't wait for one tick. There is
> something wrong with the delay that is asking for the single tick delay.

The watchdogs, by design, ask for a single tick delay.

Here it is:
https://github.com/apache/nuttx/blob/master/sched/wdog/wd_start.c#L406

When the wdog->lag is 0, then the delay is set to 1 tick.

On Wed, Jun 7, 2023 at 11:25 PM Fotis Panagiotopoulos <f.j.pa...@gmail.com>
wrote:

> > Yes, it is a free-running timer and represents the current time. It is
> > read whenever anything asks for the current time.  It is read frequently
> > during the interval timer interrupt processing to avoid/minimize
> > situations like you describe.
> > > Should the timer be stopped?
> >
> > You can't stop it or it no longer represents the current time.
>
> Understood. Also just got verified experimentally.
> The timer must run, by design.
>
> > It is possible if you make an assumption like "the maximum delay cannot
> > be larger than half the range of clock".  Then if the implied delay is
> > larger than half the range of the clock, then you can assume that we
> > tried to schedule something in the past.
> >
> > A better check would be to calculate the number of ticks until the
> > match.  This should be the same as the delay +/-  a few ticks.
>
> I am afraid that this check will not help.
> For this specific problem, you cannot perform any checks.
> Because between the time the check is performed, and the match register is
> loaded,
> the timer may have advanced.
>
> Here is the failure scenario:
> 1. Assume that the timer counter is currently at 100 ticks.
> 2. The scheduler requests a timeout in 1 tick.
> 3. The counter is read (100).
> 4. The match value is calculated (100 + 1 = 101).
> 5. It just so happens that the timer advanced to 101.
> 6. The match register is loaded with the value 101. Now it is too late.
>
> You will have to wait a full timer roll-over for the next match.
>
> No matter where you put the check, the timer will always have the chance
> to "slip" to the next value
> before you had the chance to set the match register (and re-enable the
> interrupt).
>
> > This is, ultimately, the problem.  You can't wait for one tick. There is
> > something wrong with the delay that is asking for the single tick delay.
>
> This is surely happening though!
> I added the following within up_timer_start():
>
> ASSERT(period > 1);
>
> The assertion fails immediately!
>
> I checked at least one occurence, and this is the fault:
>
> sched_unlock() -> nxsched_reassess_timer() -> nxsched_cancel_timer() -> 
> nxsched_timer_process()
> -> wd_timer()
>
> There, there is the watchdog lp_work_timer_expiry that requests a delay of
> 1 tick.
>
> But I am pretty sure there will be other cases of 1 tick wait, though...
>
>
>
>
> On Wed, Jun 7, 2023 at 10:58 PM Gregory Nutt <spudan...@gmail.com> wrote:
>
>>
>> > Later on, up_timer_start() will try to schedule the timer expiration 1
>> tick
>> > in the future.
>>
>> This is, ultimately, the problem.  You can't wait for one tick. There is
>> something wrong with the delay that is asking for the single tick delay.
>>
>> If the single tick delay is valid for some reason, then there is no
>> clean work-around:  Increase the delay? Ignore the delay?
>>
>> I don't think this should happen.  I think it is a bug of some kind.
>> For example, if interrupts are disabled for a long time so that interval
>> timer processing is delayed.  Then the delay value can be small or even
>> negative, I suppose.
>>
>> > At least in STM32 there is no protection about scheduling things to the
>> > past.
>> > As far as I can tell, it would be impossible with the current
>> > implementation.
>>
>> It is possible if you make an assumption like "the maximum delay cannot
>> be larger than half the range of clock".  Then if the implied delay is
>> larger than half the range of the clock, then you can assume that we
>> tried to schedule something in the past.
>>
>> A better check would be to calculate the number of ticks until the
>> match.  This should be the same as the delay +/-  a few ticks.
>>
>> > During all these calculations, and setting of the match register, the
>> timer
>> > is left running.
>> > Thus it can run beyond our intended target while we set it.
>> Yes, it is a free-running timer and represents the current time. It is
>> read whenever anything asks for the current time.  It is read frequently
>> during the interval timer interrupt processing to avoid/minimize
>> situations like you describe.
>> > Should the timer be stopped?
>>
>> You can't stop it or it no longer represents the current time.
>>
>>
>>

Reply via email to