Received: by 2002:a05:6358:c692:b0:131:369:b2a3 with SMTP id fe18csp4838690rwb; Mon, 31 Jul 2023 13:07:58 -0700 (PDT) X-Google-Smtp-Source: APBJJlHzoJLMQvA8mnde45pU/A8dh82klgHF7KJjzuQ6/cGvotO5gzcBxokz4mjgPZLR3MAW/e8i X-Received: by 2002:a17:902:d511:b0:1bb:1e69:28be with SMTP id b17-20020a170902d51100b001bb1e6928bemr12338221plg.42.1690834078291; Mon, 31 Jul 2023 13:07:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1690834078; cv=none; d=google.com; s=arc-20160816; b=rLWemQ8R+AMJviRCS4v/SteJoeKZ6gOiMG6wcYrVll+lw8DS0dmRHjESw/NXsSXqn6 r3Ck0gXJlG8zMW9kiOti8QPLdln2OU/SlyL+3ks8H6fD+UZB+dMDqGtGE29nxKv0VTRp nAZTh0nC6zD/4HSi4hrqEmb0eeuqNNxqmbivs10GRUicirCTxVfaC2gmu2Gb7iumT3bG vl6+H4bf1RZcn1I3RQzlLsXXH+nEdGuTZvz7JVM3YndWB/X3ynBPCtZ8zoGacWVE5JOT UCHG4kTZN0B8X9hLXH18S8qsSwnU+vm2trL72mlCxKPU5jnCZ2z5NhEQB6VvRveqVRC/ Q1rg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=JOCB7MurumYOy3aBT7ZA7TjR0snhtKDPJvlWyre0Pb4=; fh=vcb1WTwJPUMTZX6OxkyO+5cKBEoTRHpgQZ5gmsle4eE=; b=v2SvYu4KH1VpL1THNxHp73B9GEp354SKMQenIhO1IflMsWOrETqHsoKiJuCKiSLKFa sFm9Vvk/5y8ARlM2x5QpljPW2j1LQKS8SWbKWhnSyoq/VvsYb+kCN31bh8XG7RkpYxYw Y6rMlch2LC0s4uHFQxdM7uUax2AER1FSeA3Pz62aTjgpI3ZfKR0YdThYz3GOB8/Wdlhu 6T13vAEiqH8i/NVMHM2+Q8OalNSSUODjoaVytd1YNrmKEfr5FDaAB7L0mzXEwA6l/mXa C9hQ5keQfRP1Xyix2R2ayPexF82w0U3Le//OjRxS3tH43WWwCrNA2wPrO6oFLy776z36 gIkg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id u9-20020a170903124900b001bbc884362dsi7996903plh.135.2023.07.31.13.07.44; Mon, 31 Jul 2023 13:07:58 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231228AbjGaTFE (ORCPT + 99 others); Mon, 31 Jul 2023 15:05:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42706 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230381AbjGaTE5 (ORCPT ); Mon, 31 Jul 2023 15:04:57 -0400 Received: from cloudserver094114.home.pl (cloudserver094114.home.pl [79.96.170.134]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 986261710; Mon, 31 Jul 2023 12:04:55 -0700 (PDT) Received: from localhost (127.0.0.1) (HELO v370.home.net.pl) by /usr/run/smtp (/usr/run/postfix/private/idea_relay_lmtp) via UNIX with SMTP (IdeaSmtpServer 5.2.0) id d3f93b39a0953369; Mon, 31 Jul 2023 21:04:54 +0200 Authentication-Results: v370.home.net.pl; spf=softfail (domain owner discourages use of this host) smtp.mailfrom=rjwysocki.net (client-ip=195.136.19.94; helo=[195.136.19.94]; envelope-from=rjw@rjwysocki.net; receiver=) Received: from kreacher.localnet (unknown [195.136.19.94]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by v370.home.net.pl (Postfix) with ESMTPSA id AAF8A6620E2; Mon, 31 Jul 2023 21:04:53 +0200 (CEST) From: "Rafael J. Wysocki" To: Linux PM Cc: LKML , Peter Zijlstra , Anna-Maria Behnsen , Frederic Weisbecker , Kajetan Puchalski Subject: [PATCH v3 1/3] cpuidle: teo: Update idle duration estimate when choosing shallower state Date: Mon, 31 Jul 2023 20:56:35 +0200 Message-ID: <13332551.uLZWGnKmhe@kreacher> In-Reply-To: <4515817.LvFx2qVVIh@kreacher> References: <4515817.LvFx2qVVIh@kreacher> MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="UTF-8" X-CLIENT-IP: 195.136.19.94 X-CLIENT-HOSTNAME: 195.136.19.94 X-VADE-SPAMSTATE: clean X-VADE-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedviedrjeeggddutdekucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecujffqoffgrffnpdggtffipffknecuuegrihhlohhuthemucduhedtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhvfevufffkfgjfhgggfgtsehtufertddttdejnecuhfhrohhmpedftfgrfhgrvghlucflrdcuhgihshhotghkihdfuceorhhjfiesrhhjfiihshhotghkihdrnhgvtheqnecuggftrfgrthhtvghrnhepfeduudeutdeugfelffduieegiedtueefledvjeegffdttefhhffhtefhleejgfetnecuffhomhgrihhnpehkvghrnhgvlhdrohhrghenucfkphepudelhedrudefiedrudelrdelgeenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepihhnvghtpeduleehrddufeeirdduledrleegpdhhvghlohepkhhrvggrtghhvghrrdhlohgtrghlnhgvthdpmhgrihhlfhhrohhmpedftfgrfhgrvghlucflrdcuhgihshhotghkihdfuceorhhjfiesrhhjfiihshhotghkihdrnhgvtheqpdhnsggprhgtphhtthhopeeipdhrtghpthhtoheplhhinhhugidqphhmsehvghgvrhdrkhgvrhhnvghlrdhorhhgpdhrtghpthhtoheplhhinhhugidqkhgvrhhnvghlsehvghgvrhdrkhgvrhhnvghlrdhorhhgpdhrtghpthhtohepphgvthgvrhiisehinhhfrhgruggvrggurdhorhhgpdhrtghpthhtoheprghnnhgrqdhmrghrihgrsehlihhnuhht rhhonhhigidruggvpdhrtghpthhtohepfhhrvgguvghrihgtsehkvghrnhgvlhdrohhrghdprhgtphhtthhopehkrghjvghtrghnrdhpuhgthhgrlhhskhhisegrrhhmrdgtohhm X-DCC--Metrics: v370.home.net.pl 1024; Body=6 Fuz1=6 Fuz2=6 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Rafael J. Wysocki The TEO governor takes CPU utilization into account by refining idle state selection when the utilization is above a certain threshold. This is done by choosing an idle state shallower than the previously selected one. However, when doing this, the idle duration estimate needs to be adjusted so as to prevent the scheduler tick from being stopped when the candidate idle state is shallow, which may lead to excessive energy usage if the CPU is not woken up quickly enough going forward. Moreover, if the scheduler tick has been stopped already and the new idle duration estimate is too small, the replacement candidate state cannot be used. Modify the relevant code to take the above observations into account. Fixes: 9ce0f7c4bc64 ("cpuidle: teo: Introduce util-awareness") Link: https://lore.kernel.org/linux-pm/CAJZ5v0jJxHj65r2HXBTd3wfbZtsg=_StzwO1kA5STDnaPe_dWA@mail.gmail.com Signed-off-by: Rafael J. Wysocki --- v2 -> v3: * Make the handling of the "2 idle state and utilized CPU" case more straightforward. v1 -> v2: * Rework the code handling the special case when the CPU is utilized and there are only 2 idle states (drop the loop, avoid using state 0 when the tick has been stopped already and it is too shallow, check if state 1 is not disabled when about to use it, set low idle duration estimate). * Changelog edits. --- drivers/cpuidle/governors/teo.c | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) Index: linux-pm/drivers/cpuidle/governors/teo.c =================================================================== --- linux-pm.orig/drivers/cpuidle/governors/teo.c +++ linux-pm/drivers/cpuidle/governors/teo.c @@ -397,13 +397,23 @@ static int teo_select(struct cpuidle_dri * the shallowest non-polling state and exit. */ if (drv->state_count < 3 && cpu_data->utilized) { - for (i = 0; i < drv->state_count; ++i) { - if (!dev->states_usage[i].disable && - !(drv->states[i].flags & CPUIDLE_FLAG_POLLING)) { - idx = i; - goto end; - } - } + /* The CPU is utilized, so assume a short idle duration. */ + duration_ns = teo_middle_of_bin(0, drv); + /* + * If state 0 is enabled and it is not a polling one, select it + * right away unless the scheduler tick has been stopped, in + * which case care needs to be taken to leave the CPU in a deep + * enough state in case it is not woken up any time soon after + * all. If state 1 is disabled, though, state 0 must be used + * anyway. + */ + if ((!idx && !(drv->states[0].flags & CPUIDLE_FLAG_POLLING) && + teo_time_ok(duration_ns)) || dev->states_usage[1].disable) + idx = 0; + else /* Assume that state 1 is not a polling one and use it. */ + idx = 1; + + goto end; } /* @@ -539,10 +549,20 @@ static int teo_select(struct cpuidle_dri /* * If the CPU is being utilized over the threshold, choose a shallower - * non-polling state to improve latency + * non-polling state to improve latency, unless the scheduler tick has + * been stopped already and the shallower state's target residency is + * not sufficiently large. */ - if (cpu_data->utilized) - idx = teo_find_shallower_state(drv, dev, idx, duration_ns, true); + if (cpu_data->utilized) { + s64 span_ns; + + i = teo_find_shallower_state(drv, dev, idx, duration_ns, true); + span_ns = teo_middle_of_bin(i, drv); + if (teo_time_ok(span_ns)) { + idx = i; + duration_ns = span_ns; + } + } end: /*