Received: by 2002:a25:c593:0:0:0:0:0 with SMTP id v141csp2377957ybe; Tue, 3 Sep 2019 11:58:18 -0700 (PDT) X-Google-Smtp-Source: APXvYqxTYX8l3Q6NWH5AOQQ9xMSoHaOnczwyXHVzuCeeVYsHzfiJ2V9Yuc+fsQjLCrAtATjR9yQy X-Received: by 2002:a62:cb:: with SMTP id 194mr16885245pfa.130.1567537097971; Tue, 03 Sep 2019 11:58:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1567537097; cv=none; d=google.com; s=arc-20160816; b=tkCR5R1jw00UOjXSJvu3Lxw7FvW+GNxeh3AU+GWn10LogLnY5U4mDRQLJglP1+zZH/ Em+RsK+WhtZD/F9aGwdQkLjX0L0u7HxcgIE26OOCe8JNkxnTd3J/iZydx0h8zdOvxcIK 3T/O3iacP3SkqaiSq0L0phI/HNqZMEInlsmOKrXDRvqf27WlhRoJ+Kb33S/4XU3z+SS1 jv1rJmHuFSicSL8tXEFawGE7MK4ePEz0ojpw7pfG265BLQ09fUHsCMzM5zfRXmY8YWUO g/02+hGTXSHUpcXQTIhrn4CQcMEEuAXkH/ZyYbGNPeYGuoYWMIXc7j+8Z6KmT+sF0XYH RO1g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-language :content-transfer-encoding:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject; bh=vDfv16gscomWPltrdYxP3wrpm+OPvF5Kr3CPL7kRJXk=; b=Wlc+A30mLhSveCkc7GiS3sSU0z8Na8kcquSZtlev7NJmssqKMUH3+wBREdiZZWsAa4 WzqlUPR0wWGUoNDinWwCHN71/pf3+WV3uIKA1goxha4trimKBV/9oyheAwC1mIJW8zaq xMnjmQF2KaY+bsO6gP2HCMm3t4YxKuya790tkdKOEtzTRkLCDsm3Hy6UIuKhMOhB7wOi fMVe5jVpMF4bpvjVIwryhqImqrxqvG/UYon2btJguzQzjTNJh/s+8YglwYvztOVpbjIS E9qcOtb5+ZC+4JIw3uzpETKk7hby1oaprl9Ij1kr2TXgUAfrftBoyy9r4i+PWMiizhgV sGNg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id o3si15157957plb.103.2019.09.03.11.58.02; Tue, 03 Sep 2019 11:58:17 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726679AbfICSzq (ORCPT + 99 others); Tue, 3 Sep 2019 14:55:46 -0400 Received: from schedar.uberspace.de ([185.26.156.41]:53682 "EHLO schedar.uberspace.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726405AbfICSzq (ORCPT ); Tue, 3 Sep 2019 14:55:46 -0400 X-Greylist: delayed 400 seconds by postgrey-1.27 at vger.kernel.org; Tue, 03 Sep 2019 14:55:45 EDT Received: (qmail 12847 invoked from network); 3 Sep 2019 18:49:02 -0000 Received: from localhost (HELO ?192.168.188.41?) (127.0.0.1) by schedar.uberspace.de with SMTP; 3 Sep 2019 18:49:02 -0000 Subject: Re: Problem when function alarmtimer_suspend returns 0 if time delta is zero To: Thomas Gleixner , Alexandre Belloni Cc: linux-rtc@vger.kernel.org, John Stultz , Stephen Boyd , linux-kernel@vger.kernel.org References: <08fbdf25-faa1-aa13-4f13-d30acbf27dda@mipisi.de> <20190902074917.GA21922@piout.net> From: Michael Message-ID: <4fc3a016-ec2f-a15e-5fd1-6794a001e2d9@mipisi.de> Date: Tue, 3 Sep 2019 20:48:59 +0200 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:60.0) Gecko/20100101 Thunderbird/60.8.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-Language: de-DE Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Thomas, thank you very much for your patch. Unfortunately currently I can only test it with a kernel 4.1.52 but i've tried to patch your new logic into my older kernel version. There seem to be rare cases where the "delta" value becomes negative. Therefore I added if(unlikely(delta < 0)) {     delta = 0; } before min-check. Currently I still get returns here in the new code + if (min == KTIME_MAX) return 0; where the board afterwards is not woken up.So I think there is still something missing. I'm doing further tests and keep you informed. Again Thanks! Michael On 02.09.2019 12:57, Thomas Gleixner wrote: > Michael, > > On Mon, 2 Sep 2019, Alexandre Belloni wrote: >> On 31/08/2019 20:32:06+0200, Michael wrote: >>> 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. >>> 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. > No. That code is simply broken because it tries to handle the case where a > alarmtimer nanosleep got woken up by the freezer. That's broken because it > makes the delta = 0 assumption which leads to the issue you discovered. > > That whole cruft can be removed by switching alarmtimer nanosleep to use > freezable_schedule(). That keeps the timer queued and avoids all the issues. > > Completely untested patch below. > > Thanks, > > tglx > > 8<---------------------- > > kernel/time/alarmtimer.c | 57 +++-------------------------------------------- > 1 file changed, 4 insertions(+), 53 deletions(-) > > --- a/kernel/time/alarmtimer.c > +++ b/kernel/time/alarmtimer.c > @@ -46,14 +46,6 @@ static struct alarm_base { > clockid_t base_clockid; > } alarm_bases[ALARM_NUMTYPE]; > > -#if defined(CONFIG_POSIX_TIMERS) || defined(CONFIG_RTC_CLASS) > -/* freezer information to handle clock_nanosleep triggered wakeups */ > -static enum alarmtimer_type freezer_alarmtype; > -static ktime_t freezer_expires; > -static ktime_t freezer_delta; > -static DEFINE_SPINLOCK(freezer_delta_lock); > -#endif > - > #ifdef CONFIG_RTC_CLASS > static struct wakeup_source *ws; > > @@ -241,19 +233,12 @@ EXPORT_SYMBOL_GPL(alarm_expires_remainin > */ > static int alarmtimer_suspend(struct device *dev) > { > - ktime_t min, now, expires; > + ktime_t now, expires, min = KTIME_MAX; > int i, ret, type; > struct rtc_device *rtc; > unsigned long flags; > struct rtc_time tm; > > - spin_lock_irqsave(&freezer_delta_lock, flags); > - min = freezer_delta; > - expires = freezer_expires; > - type = freezer_alarmtype; > - freezer_delta = 0; > - spin_unlock_irqrestore(&freezer_delta_lock, flags); > - > rtc = alarmtimer_get_rtcdev(); > /* If we have no rtcdev, just return */ > if (!rtc) > @@ -271,13 +256,13 @@ static int alarmtimer_suspend(struct dev > if (!next) > continue; > delta = ktime_sub(next->expires, base->gettime()); > - if (!min || (delta < min)) { > + if (delta < min) { > expires = next->expires; > min = delta; > type = i; > } > } > - if (min == 0) > + if (min == KTIME_MAX) > return 0; > > if (ktime_to_ns(min) < 2 * NSEC_PER_SEC) { > @@ -479,38 +464,6 @@ u64 alarm_forward_now(struct alarm *alar > EXPORT_SYMBOL_GPL(alarm_forward_now); > > #ifdef CONFIG_POSIX_TIMERS > - > -static void alarmtimer_freezerset(ktime_t absexp, enum alarmtimer_type type) > -{ > - struct alarm_base *base; > - unsigned long flags; > - ktime_t delta; > - > - switch(type) { > - case ALARM_REALTIME: > - base = &alarm_bases[ALARM_REALTIME]; > - type = ALARM_REALTIME_FREEZER; > - break; > - case ALARM_BOOTTIME: > - base = &alarm_bases[ALARM_BOOTTIME]; > - type = ALARM_BOOTTIME_FREEZER; > - break; > - default: > - WARN_ONCE(1, "Invalid alarm type: %d\n", type); > - return; > - } > - > - delta = ktime_sub(absexp, base->gettime()); > - > - spin_lock_irqsave(&freezer_delta_lock, flags); > - if (!freezer_delta || (delta < freezer_delta)) { > - freezer_delta = delta; > - freezer_expires = absexp; > - freezer_alarmtype = type; > - } > - spin_unlock_irqrestore(&freezer_delta_lock, flags); > -} > - > /** > * clock2alarm - helper that converts from clockid to alarmtypes > * @clockid: clockid. > @@ -715,7 +668,7 @@ static int alarmtimer_do_nsleep(struct a > set_current_state(TASK_INTERRUPTIBLE); > alarm_start(alarm, absexp); > if (likely(alarm->data)) > - schedule(); > + freezable_schedule(); > > alarm_cancel(alarm); > } while (alarm->data && !signal_pending(current)); > @@ -727,8 +680,6 @@ static int alarmtimer_do_nsleep(struct a > if (!alarm->data) > return 0; > > - if (freezing(current)) > - alarmtimer_freezerset(absexp, type); > restart = ¤t->restart_block; > if (restart->nanosleep.type != TT_NONE) { > struct timespec64 rmt;