Received: by 2002:a05:7412:1492:b0:e2:908c:2ebd with SMTP id s18csp622451rdh; Tue, 22 Aug 2023 06:13:55 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEac9DwxmE7nS8AWeCHgWrdaOQfmjXs+K0uuk4s9CB530xlhBu+EtFQtDsqsr0wLfVmFL4j X-Received: by 2002:ac2:4f15:0:b0:4f8:5635:2cd8 with SMTP id k21-20020ac24f15000000b004f856352cd8mr7188718lfr.32.1692710035405; Tue, 22 Aug 2023 06:13:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1692710035; cv=none; d=google.com; s=arc-20160816; b=DkVhLuhhYDNS6UP3E+abLs+RJ7L60I2qLdaEPS6gZEE1oKuFDxY1ThIogJPvCOSKT5 cpd+4QKDaSq2C71UJ62nNnJxUHLj1Eu2l5iKKophEjeyCZRPjB3+R0/qj0YT9F5jmHdq beCCeYYmVVzbsxA1DWicSeYGu+BThwE6chq6ovnZX0RbiPkdRM3JGR3rZEuUfRewYDjY 9+PgNOIHXs7aejCi9pKOScE/FyR68+MadEiEZhkbs9vfGv6nXWCHSx/DjO18sFbG8yN6 nDKdYnsEB1O1T8BRLqDHqDLubm3Rcep2/5seozcnFaSQFRnL+eG12PfpBK4BOaCKWmDk c+dA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:cc:to:subject :message-id:date:from:in-reply-to:references:mime-version; bh=q6TcgcgTPzQ/yV34lSCrk14iTZzvOV56BMfHENf1++M=; fh=Lo+MgkAvpFMV9ox6ViV0NKGx8YHmg865ZGapze2z/uQ=; b=Hp3m6PcQGRJoLMK9IkxY3s5CXNmR+UVdb1eNbpCunoiSYhTk/PhowX5vLMbPl2xf3w /+bZsTNdeCz0PTkQjmRCViOKtnxNh+xl++IWv1gvj3y44TriLUsxLzEz8axo/Wz8yyzL mMtJPl8024CsviMBTDcUpuDRGQmrElvDfXB8gTjXLTrU5VviQ7ip/MtXT37fX0z/SpDm 0JtMv9qgsa6RSHKtModBcpVC3xs8+9y9ii5BMtWWeqGkiccH8WfLUlJO93bqDYGS22xL g5Dp2RjyvBJMtR8FW/apgODV+Ziv9NLLBr4+cxuFqwQnswF09MHHO5duRYR0KSiFJq0B seeA== 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id l4-20020a17090615c400b00987d26a0998si7353926ejd.455.2023.08.22.06.13.30; Tue, 22 Aug 2023 06:13:55 -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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234181AbjHVK6c convert rfc822-to-8bit (ORCPT + 99 others); Tue, 22 Aug 2023 06:58:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36244 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234115AbjHVK6a (ORCPT ); Tue, 22 Aug 2023 06:58:30 -0400 Received: from mail-oo1-f42.google.com (mail-oo1-f42.google.com [209.85.161.42]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D4C20E5B; Tue, 22 Aug 2023 03:58:11 -0700 (PDT) Received: by mail-oo1-f42.google.com with SMTP id 006d021491bc7-570e8bee8b5so205521eaf.1; Tue, 22 Aug 2023 03:58:11 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692701891; x=1693306691; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=dzUMRMzjXb63NCDMZbdIbs0HqsTWUd8TxRKoGYC/IaU=; b=SA1/EEI8E+9E+B4Y+4ExxCGl7lKmggpROuzE05MzpZ2E6XTP22ZtNsfkExrbQkSKu8 7ZVfBs8CIxSF7dwitfFiSKcm3dvGOmPwz4cStERfXYl6DvZPRpMg8ongm6uKdrP6/4kA bGJU66llXQw+6zFK6tK5Re4fp8asVPw2G5qOPChHjlfdcJWBKuuTOjnHcpvRmpw7bJfa Bx10PLgwFXiWnGD/EuMSbAGN99Za4TorK6Pb5zIpEdIrIyDBfkRudsl7qJx0XDUs1WoK aj+GMQJS/xzA/KT/iy9Xr2fEtysQWM62oJXfMpj0Sbj3oA/JUJ0USUCZupuSvwh8HCty tQVA== X-Gm-Message-State: AOJu0YxYganVjYnhBTKahMuhfS6xfshzLee3tQYe8cRrtjIPAc6fy6w0 SLp5uVfe24k9B3YeBfKv4+phEdLBdR4Cu12MoYmaZFqtpdI= X-Received: by 2002:a4a:e882:0:b0:570:d852:f77f with SMTP id g2-20020a4ae882000000b00570d852f77fmr4544769ooe.1.1692701891063; Tue, 22 Aug 2023 03:58:11 -0700 (PDT) MIME-Version: 1.0 References: <20230703171502.44657-1-nfraprado@collabora.com> <3bc5be02-4e05-4c5c-a247-58c4b862528d@notapiano> In-Reply-To: <3bc5be02-4e05-4c5c-a247-58c4b862528d@notapiano> From: "Rafael J. Wysocki" Date: Tue, 22 Aug 2023 12:57:59 +0200 Message-ID: Subject: Re: [PATCH] thermal/core: Don't update trip points inside the hysteresis range To: =?UTF-8?B?TsOtY29sYXMgRi4gUi4gQS4gUHJhZG8=?= Cc: "Rafael J. Wysocki" , Daniel Lezcano , AngeloGioacchino Del Regno , kernel@collabora.com, Amit Kucheria , Zhang Rui , linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8BIT X-Spam-Status: No, score=-1.4 required=5.0 tests=BAYES_00, FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS, RCVD_IN_DNSWL_BLOCKED,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL, SPF_HELO_NONE,SPF_PASS autolearn=no 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 On Tue, Aug 22, 2023 at 12:25 AM Nícolas F. R. A. Prado wrote: > > On Mon, Aug 21, 2023 at 11:10:27PM +0200, Rafael J. Wysocki wrote: > > On Mon, Jul 3, 2023 at 7:15 PM Nícolas F. R. A. Prado > > wrote: > > > > > > When searching for the trip points that need to be set, the nearest trip > > > point's temperature is used for the high trip, while the nearest trip > > > point's temperature minus the hysteresis is used for the low trip. The > > > issue with this logic is that when the current temperature is inside a > > > trip point's hysteresis range, both high and low trips will come from > > > the same trip point. As a consequence instability can still occur like > > > this: > > > * the temperature rises slightly and enters the hysteresis range of a > > > trip point > > > * polling happens and updates the trip points to the hysteresis range > > > * the temperature falls slightly, exiting the hysteresis range, crossing > > > the trip point and triggering an IRQ, the trip points are updated > > > * repeat > > > > > > So even though the current hysteresis implementation prevents > > > instability from happening due to IRQs triggering on the same > > > temperature value, both ways, it doesn't prevent it from happening due > > > to an IRQ on one way and polling on the other. > > > > > > To properly implement a hysteresis behavior, when inside the hysteresis > > > range, don't update the trip points. This way, the previously set trip > > > points will stay in effect, which will in a way remember the previous > > > state (if the temperature signal came from above or below the range) and > > > therefore have the right trip point already set. The exception is if > > > there was no previous trip point set, in which case a previous state > > > doesn't exist, and so it's sensible to allow the hysteresis range as > > > trip points. > > > > > > Signed-off-by: Nícolas F. R. A. Prado > > > > > > --- > > > > > > drivers/thermal/thermal_trip.c | 21 +++++++++++++++++++-- > > > 1 file changed, 19 insertions(+), 2 deletions(-) > > > > > > diff --git a/drivers/thermal/thermal_trip.c b/drivers/thermal/thermal_trip.c > > > index 907f3a4d7bc8..c386ac5d8bad 100644 > > > --- a/drivers/thermal/thermal_trip.c > > > +++ b/drivers/thermal/thermal_trip.c > > > @@ -57,6 +57,7 @@ void __thermal_zone_set_trips(struct thermal_zone_device *tz) > > > { > > > struct thermal_trip trip; > > > int low = -INT_MAX, high = INT_MAX; > > > + int low_trip_id = -1, high_trip_id = -2; > > > int i, ret; > > > > > > lockdep_assert_held(&tz->lock); > > > @@ -73,18 +74,34 @@ void __thermal_zone_set_trips(struct thermal_zone_device *tz) > > > > > > trip_low = trip.temperature - trip.hysteresis; > > > > > > - if (trip_low < tz->temperature && trip_low > low) > > > + if (trip_low < tz->temperature && trip_low > low) { > > > low = trip_low; > > > + low_trip_id = i; > > > + } > > > > > > > I think I get the idea, but wouldn't a similar effect be achieved by > > adding an "else" here? > > No. That would only fix the problem in one direction, namely, when the > temperature entered the hysteresis range from above. But when the temperature > entered the range from below, we'd need to check the high threshold first to > achieve the same result. > > The way I've implemented here is the simplest I could think of that works for > both directions. Well, what about the replacement patch below (untested)? --- drivers/thermal/thermal_trip.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) Index: linux-pm/drivers/thermal/thermal_trip.c =================================================================== --- linux-pm.orig/drivers/thermal/thermal_trip.c +++ linux-pm/drivers/thermal/thermal_trip.c @@ -55,6 +55,7 @@ void __thermal_zone_set_trips(struct the { struct thermal_trip trip; int low = -INT_MAX, high = INT_MAX; + bool same_trip = false; int i, ret; lockdep_assert_held(&tz->lock); @@ -63,6 +64,7 @@ void __thermal_zone_set_trips(struct the return; for (i = 0; i < tz->num_trips; i++) { + bool low_set = false; int trip_low; ret = __thermal_zone_get_trip(tz, i , &trip); @@ -71,18 +73,31 @@ void __thermal_zone_set_trips(struct the trip_low = trip.temperature - trip.hysteresis; - if (trip_low < tz->temperature && trip_low > low) + if (trip_low < tz->temperature && trip_low > low) { low = trip_low; + low_set = true; + same_trip = false; + } if (trip.temperature > tz->temperature && - trip.temperature < high) + trip.temperature < high) { high = trip.temperature; + same_trip = low_set; + } } /* No need to change trip points */ if (tz->prev_low_trip == low && tz->prev_high_trip == high) return; + /* + * If "high" and "low" are the same, skip the change unless this is the + * first time. + */ + if (same_trip && (tz->prev_low_trip != -INT_MAX || + tz->prev_high_trip != INT_MAX)) + return; + tz->prev_low_trip = low; tz->prev_high_trip = high;