<div dir="ltr">Applied to Vivid master-next.<div><br></div><div>Thanks,</div><div>Leann</div><div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jan 6, 2015 at 6:05 AM, Colin Ian King <span dir="ltr"><<a href="mailto:colin.king@canonical.com" target="_blank">colin.king@canonical.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On 06/01/15 12:48, Colin King wrote:<br>
> From: Colin Ian King <<a href="mailto:colin.king@canonical.com">colin.king@canonical.com</a>><br>
><br>
> The current enqueuing does not trigger an alarm if any expired timers<br>
> already exist on the timerqueue. This can occur when a RTC wake alarm<br>
> is used to wake a machine out of hibernate and the resumed state has<br>
> old expired timers that have not been removed from the timer queue.<br>
> This fix skips over any expired timers and triggers an alarm if there<br>
> are no pending timers on the timerqueue.<br>
><br>
> The bug was found running the example RTC timer program from<br>
> Documentation/rtc.txt; it runs fine before a hibernate but will block<br>
> forever on RTC reads after a resume from a hibernate that is woken<br>
> up using a RTC wakealarm.<br>
<br>
</span>BugLink: <a href="http://bugs.launchpad.net/bugs/1333569" target="_blank">http://bugs.launchpad.net/bugs/1333569</a><br>
<div class="HOEnZb"><div class="h5"><br>
><br>
> Signed-off-by: Colin Ian King <<a href="mailto:colin.king@canonical.com">colin.king@canonical.com</a>><br>
> ---<br>
>  drivers/rtc/interface.c | 16 +++++++++++++++-<br>
>  1 file changed, 15 insertions(+), 1 deletion(-)<br>
><br>
> diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c<br>
> index 5b2717f..ca9d9fc 100644<br>
> --- a/drivers/rtc/interface.c<br>
> +++ b/drivers/rtc/interface.c<br>
> @@ -780,9 +780,23 @@ EXPORT_SYMBOL_GPL(rtc_irq_set_freq);<br>
>   */<br>
>  static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer)<br>
>  {<br>
> +     struct timerqueue_node *next = timerqueue_getnext(&rtc->timerqueue);<br>
> +     struct rtc_time tm;<br>
> +     ktime_t now;<br>
> +<br>
>       timer->enabled = 1;<br>
> +     __rtc_read_time(rtc, &tm);<br>
> +     now = rtc_tm_to_ktime(tm);<br>
> +<br>
> +     /* Skip over expired timers */<br>
> +     while (next) {<br>
> +             if (next->expires.tv64 >= now.tv64)<br>
> +                     break;<br>
> +             next = timerqueue_iterate_next(next);<br>
> +     }<br>
> +<br>
>       timerqueue_add(&rtc->timerqueue, &timer->node);<br>
> -     if (&timer->node == timerqueue_getnext(&rtc->timerqueue)) {<br>
> +     if (!next) {<br>
>               struct rtc_wkalrm alarm;<br>
>               int err;<br>
>               alarm.time = rtc_ktime_to_tm(timer->node.expires);<br>
><br>
<br>
<br>
--<br>
</div></div><div class="HOEnZb"><div class="h5">kernel-team mailing list<br>
<a href="mailto:kernel-team@lists.ubuntu.com">kernel-team@lists.ubuntu.com</a><br>
<a href="https://lists.ubuntu.com/mailman/listinfo/kernel-team" target="_blank">https://lists.ubuntu.com/mailman/listinfo/kernel-team</a><br>
</div></div></blockquote></div><br></div></div></div>