Received: by 2002:a25:730a:0:0:0:0:0 with SMTP id o10csp958356ybc; Tue, 24 Sep 2019 17:05:19 -0700 (PDT) X-Google-Smtp-Source: APXvYqyyh3OlqEkM2n6R09cSIq+A834qVCFmxTQCXkDQLZKT3WBFBPg9uzinnCBG1pqQm19eTVNL X-Received: by 2002:a7b:c764:: with SMTP id x4mr3574853wmk.138.1569369919571; Tue, 24 Sep 2019 17:05:19 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1569369919; cv=none; d=google.com; s=arc-20160816; b=0Kwr/Xov/TCcoEH6uxtFbaclEIAQzsS+hIvrKVzzwox81r/zrpV90K2VdFihOB2iuI u5gglJvbL8Vf+1n5hT2PTf3YzRrrgiKFEw32l8KMjxaBa4hSQQ4ufSHbWIq/zXGg25eS V7xPaZ34CDJou9jg1Aatux+4qJssauIOvRgdHFzWzeP0+hXqApZkbbv54sBOlzbh49aU AsE4N+goEw9Z7IgRvMHMU+Rb9nY9ILpR+TADdzWOtNGMuGNoINRvA4h6kIXtUjdUeQYP lCcXScknOYUq2X/jVaSfMqwWl73GCiVxJDbsXxb0Z9SQuUQsO56OLPi2i2hcd9PZ/HUd ksxw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=j17a6yX+4XSbaLAfFSR3SpYIVs4iNUZF8gXf8PDDt/g=; b=XMrIR1rKa2rUHIUy1hXR+JQKUSn9xOWVa94TMdXPe1hIsMHlX7Yw4w3KrO0di3vbrr SNwhoxCVW94ZKMJ3VXn7o7lgUHRZWWWBxUFKaoJjHIkm3HhC3ygkBVPBr/8ymHOgRRr+ xLFb6MHKFzVOt/nRim8dteDFsOzIwwhEBJs3r9UBgsSs/nwTrkbm3q018ADTkMPMncjb q9djDzKe00S6+2860D+f+npRJOrIsn5CZmqMm6u6j30gn7zPZTb3Dl8FI5l7i0lnmPO9 TmOCOW9H43RHmyxgr+WJbztRvyDPUQmMOyvxh9KD3lIUq6ONwMu4oTuI6MIWm/Vx4krS Z/PA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="uN/dxcyB"; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u23si1828652ejr.204.2019.09.24.17.04.55; Tue, 24 Sep 2019 17:05:19 -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; dkim=pass header.i=@kernel.org header.s=default header.b="uN/dxcyB"; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2439284AbfIVTi0 (ORCPT + 99 others); Sun, 22 Sep 2019 15:38:26 -0400 Received: from mail.kernel.org ([198.145.29.99]:41122 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389279AbfIVSp2 (ORCPT ); Sun, 22 Sep 2019 14:45:28 -0400 Received: from sasha-vm.mshome.net (c-73-47-72-35.hsd1.nh.comcast.net [73.47.72.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 991F621907; Sun, 22 Sep 2019 18:45:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1569177928; bh=jUA7/qGpkPZLB6Bq0rXE8/podl03XvX8nzplVpOsin4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=uN/dxcyB8av3AX2/sRRqaZr8K7F4HVKFIsh2mayp05vDVR2uJ7NtCdTDSciV/0bBq HADB1h7Z77iybO1v5vfXWI2gQa2xDQHeRhN1QosAUNne87sfuBrOzuKkfbUOqFUFsg Pt3IT/f526bbQXWMnZiu1WDJN/nAzuChYK3p/ESg= From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: "Rafael J. Wysocki" , Sasha Levin Subject: [PATCH AUTOSEL 5.3 039/203] cpuidle: teo: Allow tick to be stopped if PM QoS is used Date: Sun, 22 Sep 2019 14:41:05 -0400 Message-Id: <20190922184350.30563-39-sashal@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190922184350.30563-1-sashal@kernel.org> References: <20190922184350.30563-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: "Rafael J. Wysocki" [ Upstream commit cab09f3d2d2a0a6cb3dfb678660d67a2c3764f50 ] The TEO goveror prevents the scheduler tick from being stopped (unless stopped already) if there is a PM QoS latency constraint for the given CPU and the target residency of the deepest idle state matching that constraint is below the tick boundary. However, that is problematic if CPUs with PM QoS latency constraints are idle for long times, because it effectively causes the tick to run on them all the time which is wasteful. [It is also confusing and questionable if they are full dynticks CPUs.] To address that issue, modify the TEO governor to carry out the entire search for the most suitable idle state (from the target residency perspective) even if a latency constraint is present, to allow it to determine the expected idle duration in all cases. Also, when using the last several measured idle duration values to refine the idle state selection, make it compare those values with the current expected idle duration value (instead of comparing them with the target residency of the idle state selected so far) which should prevent the tick from being retained when it makes sense to stop it sometimes (especially in the presence of PM QoS latency constraints). Fixes: b26bf6ab716f ("cpuidle: New timer events oriented governor for tickless systems") Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/cpuidle/governors/teo.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/cpuidle/governors/teo.c b/drivers/cpuidle/governors/teo.c index 7d05efdbd3c66..12d9e6cecf1de 100644 --- a/drivers/cpuidle/governors/teo.c +++ b/drivers/cpuidle/governors/teo.c @@ -242,7 +242,7 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, struct teo_cpu *cpu_data = per_cpu_ptr(&teo_cpus, dev->cpu); int latency_req = cpuidle_governor_latency_req(dev->cpu); unsigned int duration_us, count; - int max_early_idx, idx, i; + int max_early_idx, constraint_idx, idx, i; ktime_t delta_tick; if (cpu_data->last_state >= 0) { @@ -257,6 +257,7 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, count = 0; max_early_idx = -1; + constraint_idx = drv->state_count; idx = -1; for (i = 0; i < drv->state_count; i++) { @@ -286,16 +287,8 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, if (s->target_residency > duration_us) break; - if (s->exit_latency > latency_req) { - /* - * If we break out of the loop for latency reasons, use - * the target residency of the selected state as the - * expected idle duration to avoid stopping the tick - * as long as that target residency is low enough. - */ - duration_us = drv->states[idx].target_residency; - goto refine; - } + if (s->exit_latency > latency_req && constraint_idx > i) + constraint_idx = i; idx = i; @@ -321,7 +314,13 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, duration_us = drv->states[idx].target_residency; } -refine: + /* + * If there is a latency constraint, it may be necessary to use a + * shallower idle state than the one selected so far. + */ + if (constraint_idx < idx) + idx = constraint_idx; + if (idx < 0) { idx = 0; /* No states enabled. Must use 0. */ } else if (idx > 0) { @@ -331,13 +330,12 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, /* * Count and sum the most recent idle duration values less than - * the target residency of the state selected so far, find the - * max. + * the current expected idle duration value. */ for (i = 0; i < INTERVALS; i++) { unsigned int val = cpu_data->intervals[i]; - if (val >= drv->states[idx].target_residency) + if (val >= duration_us) continue; count++; @@ -356,8 +354,10 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, * would be too shallow. */ if (!(tick_nohz_tick_stopped() && avg_us < TICK_USEC)) { - idx = teo_find_shallower_state(drv, dev, idx, avg_us); duration_us = avg_us; + if (drv->states[idx].target_residency > avg_us) + idx = teo_find_shallower_state(drv, dev, + idx, avg_us); } } } -- 2.20.1