Received: by 2002:a05:7412:1492:b0:e2:908c:2ebd with SMTP id s18csp304923rdh; Mon, 21 Aug 2023 16:31:18 -0700 (PDT) X-Google-Smtp-Source: AGHT+IG2VT/NmGXzxU9iqOLUHc+yjsBNsHQQlyPINLBJwKbK7cxpRouUGquD6kK15OOZfxQC/iZ6 X-Received: by 2002:a17:906:28c:b0:99d:fcb7:60db with SMTP id 12-20020a170906028c00b0099dfcb760dbmr9423092ejf.16.1692660678749; Mon, 21 Aug 2023 16:31:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1692660678; cv=none; d=google.com; s=arc-20160816; b=YhxCoLZCJ1pOsO2nIjRMXbDZSVkH3zr1YJb5628iCa4+yMRmFkvRPBcS+J3mwEjFn3 SYLlNfOuDygNS4Fkj5AJJ73UBgxFuT3OpeTvZ7UpTBaChO4F5UvUvrTEPiVq0rS8bLK9 GsWsUOAERK5iKybVD3++JLtUuuvgnz81PLvrFN+er63C2YHKqORgqFu9lQTAWJGZ1Rl3 eBdw13vwCbHfQDeVz78ECwPqP3ExUCLIg9ANvLueLKY9amj2IuFr9a7jXW3AZM7RehVA plE73kUeGR8X0lzG+V42KHjFACJJoVF0vwnlSBfip0HlcqgBUSzjn2jQf58M2JNr1uvQ 11Fg== 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=8EGYlk/GjjXH1AJLxDVCDZpP1X2cXlV6zEGw+GK4+Fo=; fh=WHS4mvKBulPT4vnBMwGjAA9IAlGm50oR0/0GAOoNZZk=; b=obyaQR6b+jhR6W4Ka+KxXBR7JaSKFdwWlq+r5qskFJoxV4d/AazxgTdJWJqMKoqlww tjlE36NTuRO4WdGnP1aei9Zw9Ms/qD0cqqoE3oexr4cLJ5eHvvSHh0DTL3FQ1vJ/ZFP0 rG1UIFIL5HuvJFr1W+XRKYhbomc4F6oJITzVYN89n2J6NW3eOd4rc7Hg6o/qB7smzPIH tOX5aCxTlI2jC+hSqYTsYK3qKVon6c5EI6xXh11t6s6RzkZKvgURChCWV1ZMa02yXYs2 4FJl1H2DO/5Nbso+k37G1o1zyWXYnxXmLyiaa1BSjl8d3DShhzFGQzwRyvRGICbt5Usq MP6A== 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 k9-20020a17090646c900b00993686e193csi6482629ejs.53.2023.08.21.16.30.54; Mon, 21 Aug 2023 16:31:18 -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 S229892AbjHUVKm convert rfc822-to-8bit (ORCPT + 99 others); Mon, 21 Aug 2023 17:10:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36174 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229864AbjHUVKl (ORCPT ); Mon, 21 Aug 2023 17:10:41 -0400 Received: from mail-oo1-f46.google.com (mail-oo1-f46.google.com [209.85.161.46]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2A821113; Mon, 21 Aug 2023 14:10:39 -0700 (PDT) Received: by mail-oo1-f46.google.com with SMTP id 006d021491bc7-56e280cc606so534057eaf.1; Mon, 21 Aug 2023 14:10:39 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692652238; x=1693257038; 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=i3VkaElbXUDdfTX416XO4ch3nnzvO+a6QraObVmCpUU=; b=AYOfw0U238ptNbH+/xQ65RxeU1j/DZhzjaoSihEA8wetJB0ORdrzoF1tdu9Y3pdKpw MjuFG08tqKbQ9rFyQqXQvs4X9ocwLx3XTr9nEl+LVvLBsJIpA0cLyjrYNs6lNfHjtPnV 8o3rK+mjzXtdNm/RPbAvPqG2R6FNvQ5zQXqxXtSOwSzjTK/73a4vmnHnhjX5q8yDFRXf iIEyj0K2v5UKKVI3fqyqnVCBRiufTM/tksux4+cV8b9Sc7Mdw47ae72pEli+lVT+ErBu HSnDQHu8tEBGa961RY6p49g9TuPrQday/SL8PwbPwbto3urofDNxZo2KO0t27OUy17jX je7g== X-Gm-Message-State: AOJu0Ywuila9quvv2l+tE8UVk28WtdhTxfiPFEhRMgMrd2pr1QlHsAju HLtnHQqRdzaGBYVNBeHVmqrZPWempL1dXUIFRdbCGWeC X-Received: by 2002:a4a:37c3:0:b0:570:cad0:fce9 with SMTP id r186-20020a4a37c3000000b00570cad0fce9mr3955923oor.1.1692652238387; Mon, 21 Aug 2023 14:10:38 -0700 (PDT) MIME-Version: 1.0 References: <20230703171502.44657-1-nfraprado@collabora.com> In-Reply-To: <20230703171502.44657-1-nfraprado@collabora.com> From: "Rafael J. Wysocki" Date: Mon, 21 Aug 2023 23:10:27 +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 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? > if (trip.temperature > tz->temperature && > - trip.temperature < high) > + trip.temperature < high) { > high = trip.temperature; > + high_trip_id = i; > + } > } > > /* No need to change trip points */ > if (tz->prev_low_trip == low && tz->prev_high_trip == high) > return; > > + /* > + * If the current temperature is inside a trip point's hysteresis range, > + * don't update the trip points, rely on the previously set ones to > + * rememember the previous state. > + * > + * Unless no previous trip point was set, in which case there's no > + * previous state to remember. > + */ > + if ((tz->prev_low_trip > -INT_MAX || tz->prev_high_trip < INT_MAX) && > + low_trip_id == high_trip_id) > + return; > + > tz->prev_low_trip = low; > tz->prev_high_trip = high; > > --