From patchwork Fri Jul 20 00:38:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 142392 Delivered-To: patches@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp2346336ljj; Thu, 19 Jul 2018 17:39:00 -0700 (PDT) X-Received: by 2002:a17:902:1101:: with SMTP id d1-v6mr11937065pla.147.1532047140796; Thu, 19 Jul 2018 17:39:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1532047140; cv=none; d=google.com; s=arc-20160816; b=kkKNH7JpQOz8iRpvfMSXBTSHmkqGW7TBX5VQPMtW22aMVsRaSEFWAVJsjO5gwMS/QY 3jxFxZXH33tjyjUVaknsiSln4lQdW46XmCMGTERLckwbo4cgjr2dNPuiC7ho74A2xBXZ Ftw2788lHphEztIiPTQITYPFOB+4p5wnpIPhXqlH2WVYmxvWCnfuBbYhsUKZa0Rlu4lT HfJEM2rRG6Lfc1syGGwiYdmIroEualllqvYz2BpmzjSnRTW+QXnMy3k5Dt25e6Qo70N9 xsthKI+sE1MvhDyYOBjGuH/LLtiuN+NyCBZuo4qPVmStxtlYnKbBrcrcEjomc3FnWMAV LDYg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=cl8QC7cI0N14M5eI441ZKx5bQCWuSElbitp4+Wv2+PI=; b=UYHMtsTR32r1wB5vYiInfcxs7oOCG4WLlWNYggsJjUmWtBiXbRqQnG5HhBgodTIq4G G0M1h7U2acmmI9Q4T07gSjGVcESg2m+LkYMelB/sLb11+TUpOjXmTBIazLbP3mFc3Nt/ GCme6vx/mT+CBZVe+wgYZPcGj1l5hyWJE7r4zue40BD5KTHTtb+7QE/+9ZiFJHVx50O/ Avl1u0jPJBIFHB++gYc8lbnsGznjEZSydOfI9kQvVXCcY5TQkqNqu2KiiuUD7uRZCiAH n52PqLDBX8iMANo5Lbv6VrYVuXMlWuTVtPTc9XfuQgrxS/5dnZwsSysJMWtoA+Ug93hU G9Yg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=kZa21Kgl; spf=pass (google.com: domain of john.stultz@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=john.stultz@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id 67-v6sor153382pfn.82.2018.07.19.17.39.00 for (Google Transport Security); Thu, 19 Jul 2018 17:39:00 -0700 (PDT) Received-SPF: pass (google.com: domain of john.stultz@linaro.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=kZa21Kgl; spf=pass (google.com: domain of john.stultz@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=john.stultz@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=cl8QC7cI0N14M5eI441ZKx5bQCWuSElbitp4+Wv2+PI=; b=kZa21KglaWxEqM0xlsSMhBsjKtDHjIsjIc/dubcPVir2DW9U8llDy+eAreRtz+VPh+ cWqO76umVmOZFcOntsn9yeFCXsieBUOlICtJmqyK4xT1B3x8JL9CdZ1wZMtvebl3ocmh nno1CBnc/UsIQhPmKYV654C4AWkvueafBp0mA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=cl8QC7cI0N14M5eI441ZKx5bQCWuSElbitp4+Wv2+PI=; b=bHDogBejyUwGVwzGr2tZEf55vYRzneRYSSkZ3V51WyAGxvxP+Ax4a8xmPvrEXEkNHi R4zXpXhfr+T8v13L469vrr+4E/opASXkCUvZezFh3UQapNZ/923dJD+X5/ds1SFntuIJ kVj326E5LmWaiv/cqKR/82dAxbOVXLe/LJJzY2HttG26UF82i3xnTMOyH6vKz7LUamQl 60JQtGq5UEWdFGlOxddelTdM2jjNEB/cGbuEUWWA7yU8AST6ryjVz0M+prWG+xxMPlPq /U4jA+mw5I59STN8yUcD2kazHBbFVs6rbFCcrA/9/G35O9OTDfU4p3O2srRFAzmkTWs4 qMfw== X-Gm-Message-State: AOUpUlFftqCjR+ryWa7KlQ6BS2/9ht+OYNpRdQMVMaN6gthHwr80Y2P7 0EsI6Cs5wl40IAch74fjm+WsxXqUJgzROw== X-Google-Smtp-Source: AAOMgpdZMCHoelfAac2uKmtq5tf76cMfbWlEC4ja5MThwTlFypp2jexX82UyVQu999XmIONGF03Dqw== X-Received: by 2002:a62:864a:: with SMTP id x71-v6mr11744256pfd.252.1532047140290; Thu, 19 Jul 2018 17:39:00 -0700 (PDT) Return-Path: Received: from localhost.localdomain ([2601:1c2:600:5100:4e72:b9ff:fe99:466a]) by smtp.gmail.com with ESMTPSA id x5-v6sm383881pfh.67.2018.07.19.17.38.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 19 Jul 2018 17:38:59 -0700 (PDT) From: John Stultz To: lkml Cc: Mukesh Ojha , Thomas Gleixner , Ingo Molnar , Miroslav Lichvar , Richard Cochran , Prarit Bhargava , Stephen Boyd , John Stultz Subject: [PATCH 4/5] time: Fix extra sleeptime injection when suspend fails Date: Thu, 19 Jul 2018 17:38:46 -0700 Message-Id: <1532047127-26699-5-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1532047127-26699-1-git-send-email-john.stultz@linaro.org> References: <1532047127-26699-1-git-send-email-john.stultz@linaro.org> From: Mukesh Ojha Currently, there exists a corner case assuming when there is only one clocksource e.g RTC, and system failed to go to suspend mode. While resume rtc_resume() injects the sleeptime as timekeeping_rtc_skipresume() returned 'false' (default value of sleeptime_injected) due to which we can see mismatch in timestamps. This issue can also come in a system where more than one clocksource are present and very first suspend fails. Success case: ------------ {sleeptime_injected=false} rtc_suspend() => timekeeping_suspend() => timekeeping_resume() => (sleeptime injected) rtc_resume() Failure case: ------------ {failure in sleep path} {sleeptime_injected=false} rtc_suspend() => rtc_resume() {sleeptime injected again which was not required as the suspend failed} Fix this by handling the boolean logic properly. Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Miroslav Lichvar Cc: Richard Cochran Cc: Prarit Bhargava Cc: Stephen Boyd Originally-by: Thomas Gleixner Signed-off-by: Mukesh Ojha Signed-off-by: John Stultz --- kernel/time/timekeeping.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) -- 2.7.4 diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 7033ac1..19414b1 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -1519,8 +1519,20 @@ void __weak read_boot_clock64(struct timespec64 *ts) ts->tv_nsec = 0; } -/* Flag for if timekeeping_resume() has injected sleeptime */ -static bool sleeptime_injected; +/* + * Flag reflecting whether timekeeping_resume() has injected sleeptime. + * + * The flag starts of false and is only set when a suspend reaches + * timekeeping_suspend(), timekeeping_resume() sets it to false when the + * timekeeper clocksource is not stopping across suspend and has been + * used to update sleep time. If the timekeeper clocksource has stopped + * then the flag stays true and is used by the RTC resume code to decide + * whether sleeptime must be injected and if so the flag gets false then. + * + * If a suspend fails before reaching timekeeping_resume() then the flag + * stays false and prevents erroneous sleeptime injection. + */ +static bool suspend_timing_needed; /* Flag for if there is a persistent clock on this platform */ static bool persistent_clock_exists; @@ -1619,7 +1631,7 @@ static void __timekeeping_inject_sleeptime(struct timekeeper *tk, */ bool timekeeping_rtc_skipresume(void) { - return sleeptime_injected; + return !suspend_timing_needed; } /** @@ -1655,6 +1667,8 @@ void timekeeping_inject_sleeptime64(const struct timespec64 *delta) raw_spin_lock_irqsave(&timekeeper_lock, flags); write_seqcount_begin(&tk_core.seq); + suspend_timing_needed = false; + timekeeping_forward_now(tk); __timekeeping_inject_sleeptime(tk, delta); @@ -1679,8 +1693,8 @@ void timekeeping_resume(void) unsigned long flags; struct timespec64 ts_new, ts_delta; u64 cycle_now; + bool inject_sleeptime = false; - sleeptime_injected = false; read_persistent_clock64(&ts_new); clockevents_resume(); @@ -1710,14 +1724,16 @@ void timekeeping_resume(void) tk->tkr_mono.mask); nsec = mul_u64_u32_shr(cyc_delta, clock->mult, clock->shift); ts_delta = ns_to_timespec64(nsec); - sleeptime_injected = true; + inject_sleeptime = true; } else if (timespec64_compare(&ts_new, &timekeeping_suspend_time) > 0) { ts_delta = timespec64_sub(ts_new, timekeeping_suspend_time); - sleeptime_injected = true; + inject_sleeptime = true; } - if (sleeptime_injected) + if (inject_sleeptime) { + suspend_timing_needed = false; __timekeeping_inject_sleeptime(tk, &ts_delta); + } /* Re-base the last cycle value */ tk->tkr_mono.cycle_last = cycle_now; @@ -1752,6 +1768,8 @@ int timekeeping_suspend(void) if (timekeeping_suspend_time.tv_sec || timekeeping_suspend_time.tv_nsec) persistent_clock_exists = true; + suspend_timing_needed = true; + raw_spin_lock_irqsave(&timekeeper_lock, flags); write_seqcount_begin(&tk_core.seq); timekeeping_forward_now(tk);