lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20190902074917.GA21922@piout.net>
Date:   Mon, 2 Sep 2019 09:49:17 +0200
From:   Alexandre Belloni <alexandre.belloni@...tlin.com>
To:     Michael <michael@...isi.de>
Cc:     linux-rtc@...r.kernel.org, Thomas Gleixner <tglx@...utronix.de>,
        John Stultz <john.stultz@...aro.org>,
        Stephen Boyd <sboyd@...nel.org>, linux-kernel@...r.kernel.org
Subject: Re: Problem when function alarmtimer_suspend returns 0 if time delta
 is zero

Hello Michael,

This code is maintained by the timekeeping maintainers, now in Cc and I
think John will be able to answer.

On 31/08/2019 20:32:06+0200, Michael wrote:
> Dear members of the linux-rtc list,
> 
> currently I have a problem with the alarmtimer i'm using to cyclically wake
> up my i.MX6 ULL board from suspend to RAM.
> 
> The problem is that in principle the timer wake ups work fine but seem to be
> not 100% stable. In about 1 percent the wake up alarm from suspend is
> missing.
> 
> When I look at the code of alarmtimer in function alarmtimer_suspend
> (kernel/time/alarmtimer.c)
> I find the following:
> 
> ....
> 
> /* Find the soonest timer to expire*/
> 
>     for (i = 0; i < ALARM_NUMTYPE; i++) {
>         struct alarm_base *base = &alarm_bases[i];
>         struct timerqueue_node *next;
>         ktime_t delta;
> 
>         spin_lock_irqsave(&base->lock, flags);
>         next = timerqueue_getnext(&base->timerqueue);
>         spin_unlock_irqrestore(&base->lock, flags);
>         if (!next)
>             continue;
>         delta = ktime_sub(next->expires, base->gettime());
>         if (!min || (delta < min)) {
>             expires = next->expires;
>             min = delta;
>             type = i;
>         }
>     }
>     if (min == 0)
>         return 0;
> 
>     if (ktime_to_ns(min) < 2 * NSEC_PER_SEC) {
>         __pm_wakeup_event(ws, 2 * MSEC_PER_SEC);
>         return -EBUSY;
>     }
> 
> In my error case the alarm wake up always fails if the path "if(min==0)" is
> entered. If I understand this code correctly that means that
> when ever one of the timers in the list has a remaining tick time of zero,
> the function just returns 0 and continues the suspend process until
> it reaches suspend mode.
> 
> If I implement a hack here "if(min == 0) {min = 1;}" and do not return, my
> system runs 100% ok, as the following -EBUSY path is hit.
> 
> So my question to you is: Why is there a check if min < 2 seconds and do a
> return -EBUSY here, but handle (min==0) differently?
> Could there be some race condition here, where the function
> alarmtimer_suspend just returns 0 and shortly after this the alarmtimer
> expires
> right before the RTC driver was able to allow the wake up interrupt?
> 
> If I look through the kernel versions I found the alarmtimer_suspend to be a
> very stable function, so I don't think there is anything wrong here.
> 
> But do you have a hint for me where else I could have a look to encircle the
> error?
> 
> Thank you very much!
> 
> Br,
> Michael
> 

-- 
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ