From patchwork Tue Sep 10 09:27:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Rafael J. Wysocki" X-Patchwork-Id: 13798194 Received: from cloudserver094114.home.pl (cloudserver094114.home.pl [79.96.170.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C35EA188CC1; Tue, 10 Sep 2024 09:43:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=79.96.170.134 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725961392; cv=none; b=lAak0nVOnGG3udsLelh1eLjc5/MVEE4csrUn1YtX1a6wVp0Djz83/031h8PzMuTRi2cfLQcn3waj0WE8waNb3z66q3XqM6kFVfan3rukZ+pwFvzbVr7695Q7I1PgSb5EhrzkAkyrw3wG4WqM2o28Fns4UW2qUUunYwm9pSSuqNw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725961392; c=relaxed/simple; bh=BRfixD8ukgBaZKSp2YnvGEiPR8ycPlOqNkoGGidfO6w=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=tj6SfncKlMV2+MaTvCtDwMkw/VcELl67imTHJGpDJQJ6wWP5AZ1W3XmXdiu92isNtY1fpsJSl/57peiRrtJWKQmJCfvrkbXKSmAZrbv6wrn18sIhZ1wEC66xt8zVkIO43ojWZcw0RLgsHZYX7vsOp3daYK6pSq/I3gQazn7edpg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rjwysocki.net; spf=pass smtp.mailfrom=rjwysocki.net; dkim=fail (2048-bit key) header.d=rjwysocki.net header.i=@rjwysocki.net header.b=K7V9sdNK reason="signature verification failed"; arc=none smtp.client-ip=79.96.170.134 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rjwysocki.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rjwysocki.net Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=rjwysocki.net header.i=@rjwysocki.net header.b="K7V9sdNK" 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 6.2.0) id 89051e00c9a54e99; Tue, 10 Sep 2024 11:43:07 +0200 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 cloudserver094114.home.pl (Postfix) with ESMTPSA id 55B7E6B836A; Tue, 10 Sep 2024 11:43:07 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=rjwysocki.net; s=dkim; t=1725961387; bh=BRfixD8ukgBaZKSp2YnvGEiPR8ycPlOqNkoGGidfO6w=; h=From:Subject:Date; b=K7V9sdNKT72vjYiPjwIMz9h3TsMoeJoo3hykVHXDOc4FV4VkuEOf1JorBbjOCWa9Z OOJ9tfSmrOEQrdC19sry7a0RRmTm6pUATh1XFKNZbMOb4YUaLORppxl9hW4IEqeI7C 0Hb1wtzHQHmoYPnMjP84XHsvO97KfXOF09zs/pdFCxIlyqRM7CeXOQmbPspNhWh+18 ouebrerT/XO/KLe8q7ZA9XvEl+znQ3lMR+dDmjPcSCmmwKxuwVH+O9iu7PeMcRtDo0 jvgcAtLxFooz9b1A6W7t6IGueQHz3JC/czSYniYtBE0vV70N5jyD5OJ5qEfr0Gwr6o GZlpoNLMZwXGQ== From: "Rafael J. Wysocki" To: Linux PM Cc: LKML , Daniel Lezcano , Lukasz Luba , Zhang Rui Subject: [PATCH for 6.13 v1 1/8] thermal: core: Move lists of thermal instances to trip descriptors Date: Tue, 10 Sep 2024 11:27:52 +0200 Message-ID: <2196792.irdbgypaU6@rjwysocki.net> In-Reply-To: <4920970.GXAFRqVoOG@rjwysocki.net> References: <4920970.GXAFRqVoOG@rjwysocki.net> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-CLIENT-IP: 195.136.19.94 X-CLIENT-HOSTNAME: 195.136.19.94 X-VADE-SPAMSTATE: spam:low X-VADE-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeftddrudeiledgudekucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecujffqoffgrffnpdggtffipffknecuuegrihhlohhuthemucduhedtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenogfuphgrmhfkphculdeftddtmdenucfjughrpefhvfevufffkfgjfhgggfgtsehtufertddttdejnecuhfhrohhmpedftfgrfhgrvghlucflrdcuhgihshhotghkihdfuceorhhjfiesrhhjfiihshhotghkihdrnhgvtheqnecuggftrfgrthhtvghrnhepvdffueeitdfgvddtudegueejtdffteetgeefkeffvdeftddttdeuhfegfedvjefhnecukfhppeduleehrddufeeirdduledrleegnecuufhprghmkfhppeduleehrddufeeirdduledrleegnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehinhgvthepudelhedrudefiedrudelrdelgedphhgvlhhopehkrhgvrggthhgvrhdrlhhotggrlhhnvghtpdhmrghilhhfrhhomheprhhjfiesrhhjfiihshhotghkihdrnhgvthdpnhgspghrtghpthhtohephedprhgtphhtthhopehlihhnuhigqdhpmhesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopehlihhnuhigqdhkvghrnhgvlhesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopegurghnihgvlhdrlhgviigtrghnoheslhhinhgrrhhordhorhhgpdhrtghpthhtoheplhhukhgrshiirdhluhgsrgesrghrmhdrtghomhdprhgtphhtthhopehruhhirdiihhgrnhhgsehinhhtvghlrdgtohhm X-DCC--Metrics: v370.home.net.pl 1024; Body=20 Fuz1=20 Fuz2=20 From: Rafael J. Wysocki In almost all places where a thermal zone's list of thermal instances is walked, there is a check to match a specific trip point and it is walked in vain whenever there are no cooling devices associated with the given trip. To address this, store the lists of thermal instances in trip point descriptors instead of storing them in thermal zones and adjust all code using those lists accordingly. No intentional functional impact. Signed-off-by: Rafael J. Wysocki --- drivers/thermal/gov_bang_bang.c | 11 ++++----- drivers/thermal/gov_fair_share.c | 16 ++++--------- drivers/thermal/gov_power_allocator.c | 41 ++++++++++++++-------------------- drivers/thermal/gov_step_wise.c | 16 ++++++------- drivers/thermal/thermal_core.c | 33 +++++++++++++++------------ drivers/thermal/thermal_core.h | 5 +--- drivers/thermal/thermal_helpers.c | 5 ++-- 7 files changed, 60 insertions(+), 67 deletions(-) Index: linux-pm/drivers/thermal/thermal_core.c =================================================================== --- linux-pm.orig/drivers/thermal/thermal_core.c +++ linux-pm/drivers/thermal/thermal_core.c @@ -488,7 +488,7 @@ static void thermal_zone_device_check(st static void thermal_zone_device_init(struct thermal_zone_device *tz) { - struct thermal_instance *pos; + struct thermal_trip_desc *td; INIT_DELAYED_WORK(&tz->poll_queue, thermal_zone_device_check); @@ -496,8 +496,12 @@ static void thermal_zone_device_init(str tz->passive = 0; tz->prev_low_trip = -INT_MAX; tz->prev_high_trip = INT_MAX; - list_for_each_entry(pos, &tz->thermal_instances, tz_node) - pos->initialized = false; + for_each_trip_desc(tz, td) { + struct thermal_instance *instance; + + list_for_each_entry(instance, &td->thermal_instances, trip_node) + instance->initialized = false; + } } static void thermal_governor_trip_crossed(struct thermal_governor *governor, @@ -761,12 +765,12 @@ struct thermal_zone_device *thermal_zone * Return: 0 on success, the proper error value otherwise. */ static int thermal_bind_cdev_to_trip(struct thermal_zone_device *tz, - const struct thermal_trip *trip, + struct thermal_trip *trip, struct thermal_cooling_device *cdev, struct cooling_spec *cool_spec) { - struct thermal_instance *dev; - struct thermal_instance *pos; + struct thermal_trip_desc *td = trip_to_trip_desc(trip); + struct thermal_instance *dev, *instance; bool upper_no_limit; int result; @@ -829,13 +833,13 @@ static int thermal_bind_cdev_to_trip(str goto remove_trip_file; mutex_lock(&cdev->lock); - list_for_each_entry(pos, &tz->thermal_instances, tz_node) - if (pos->trip == trip && pos->cdev == cdev) { + list_for_each_entry(instance, &td->thermal_instances, trip_node) + if (instance->cdev == cdev) { result = -EEXIST; break; } if (!result) { - list_add_tail(&dev->tz_node, &tz->thermal_instances); + list_add_tail(&dev->trip_node, &td->thermal_instances); list_add_tail(&dev->cdev_node, &cdev->thermal_instances); atomic_set(&tz->need_update, 1); @@ -869,15 +873,16 @@ free_mem: * This function is usually called in the thermal zone device .unbind callback. */ static void thermal_unbind_cdev_from_trip(struct thermal_zone_device *tz, - const struct thermal_trip *trip, + struct thermal_trip *trip, struct thermal_cooling_device *cdev) { + struct thermal_trip_desc *td = trip_to_trip_desc(trip); struct thermal_instance *pos, *next; mutex_lock(&cdev->lock); - list_for_each_entry_safe(pos, next, &tz->thermal_instances, tz_node) { - if (pos->trip == trip && pos->cdev == cdev) { - list_del(&pos->tz_node); + list_for_each_entry_safe(pos, next, &td->thermal_instances, trip_node) { + if (pos->cdev == cdev) { + list_del(&pos->trip_node); list_del(&pos->cdev_node); thermal_governor_update_tz(tz, THERMAL_TZ_UNBIND_CDEV); @@ -1414,7 +1419,6 @@ thermal_zone_device_register_with_trips( } } - INIT_LIST_HEAD(&tz->thermal_instances); INIT_LIST_HEAD(&tz->node); ida_init(&tz->ida); mutex_init(&tz->lock); @@ -1438,6 +1442,7 @@ thermal_zone_device_register_with_trips( tz->num_trips = num_trips; for_each_trip_desc(tz, td) { td->trip = *trip++; + INIT_LIST_HEAD(&td->thermal_instances); /* * Mark all thresholds as invalid to start with even though * this only matters for the trips that start as invalid and Index: linux-pm/drivers/thermal/thermal_core.h =================================================================== --- linux-pm.orig/drivers/thermal/thermal_core.h +++ linux-pm/drivers/thermal/thermal_core.h @@ -30,6 +30,7 @@ struct thermal_trip_desc { struct thermal_trip trip; struct thermal_trip_attrs trip_attrs; struct list_head notify_list_node; + struct list_head thermal_instances; int notify_temp; int threshold; }; @@ -93,7 +94,6 @@ struct thermal_governor { * @tzp: thermal zone parameters * @governor: pointer to the governor for this thermal zone * @governor_data: private pointer for governor data - * @thermal_instances: list of &struct thermal_instance of this thermal zone * @ida: &struct ida to generate unique id for this zone's cooling * devices * @lock: lock to protect thermal_instances list @@ -128,7 +128,6 @@ struct thermal_zone_device { struct thermal_zone_params *tzp; struct thermal_governor *governor; void *governor_data; - struct list_head thermal_instances; struct ida ida; struct mutex lock; struct list_head node; @@ -223,7 +222,7 @@ struct thermal_instance { struct device_attribute attr; char weight_attr_name[THERMAL_NAME_LENGTH]; struct device_attribute weight_attr; - struct list_head tz_node; /* node in tz->thermal_instances */ + struct list_head trip_node; /* node in trip->thermal_instances */ struct list_head cdev_node; /* node in cdev->thermal_instances */ unsigned int weight; /* The weight of the cooling device */ bool upper_no_limit; Index: linux-pm/drivers/thermal/gov_bang_bang.c =================================================================== --- linux-pm.orig/drivers/thermal/gov_bang_bang.c +++ linux-pm/drivers/thermal/gov_bang_bang.c @@ -67,6 +67,7 @@ static void bang_bang_control(struct the const struct thermal_trip *trip, bool crossed_up) { + const struct thermal_trip_desc *td = trip_to_trip_desc(trip); struct thermal_instance *instance; lockdep_assert_held(&tz->lock); @@ -75,10 +76,8 @@ static void bang_bang_control(struct the thermal_zone_trip_id(tz, trip), trip->temperature, tz->temperature, trip->hysteresis); - list_for_each_entry(instance, &tz->thermal_instances, tz_node) { - if (instance->trip == trip) - bang_bang_set_instance_target(instance, crossed_up); - } + list_for_each_entry(instance, &td->thermal_instances, trip_node) + bang_bang_set_instance_target(instance, crossed_up); } static void bang_bang_manage(struct thermal_zone_device *tz) @@ -104,8 +103,8 @@ static void bang_bang_manage(struct ther * to the thermal zone temperature and the trip point threshold. */ turn_on = tz->temperature >= td->threshold; - list_for_each_entry(instance, &tz->thermal_instances, tz_node) { - if (!instance->initialized && instance->trip == trip) + list_for_each_entry(instance, &td->thermal_instances, trip_node) { + if (!instance->initialized) bang_bang_set_instance_target(instance, turn_on); } } Index: linux-pm/drivers/thermal/gov_fair_share.c =================================================================== --- linux-pm.orig/drivers/thermal/gov_fair_share.c +++ linux-pm/drivers/thermal/gov_fair_share.c @@ -44,7 +44,7 @@ static int get_trip_level(struct thermal /** * fair_share_throttle - throttles devices associated with the given zone * @tz: thermal_zone_device - * @trip: trip point + * @td: trip point descriptor * @trip_level: number of trips crossed by the zone temperature * * Throttling Logic: This uses three parameters to calculate the new @@ -61,29 +61,23 @@ static int get_trip_level(struct thermal * new_state of cooling device = P3 * P2 * P1 */ static void fair_share_throttle(struct thermal_zone_device *tz, - const struct thermal_trip *trip, + const struct thermal_trip_desc *td, int trip_level) { struct thermal_instance *instance; int total_weight = 0; int nr_instances = 0; - list_for_each_entry(instance, &tz->thermal_instances, tz_node) { - if (instance->trip != trip) - continue; - + list_for_each_entry(instance, &td->thermal_instances, trip_node) { total_weight += instance->weight; nr_instances++; } - list_for_each_entry(instance, &tz->thermal_instances, tz_node) { + list_for_each_entry(instance, &td->thermal_instances, trip_node) { struct thermal_cooling_device *cdev = instance->cdev; u64 dividend; u32 divisor; - if (instance->trip != trip) - continue; - dividend = trip_level; dividend *= cdev->max_state; divisor = tz->num_trips; @@ -116,7 +110,7 @@ static void fair_share_manage(struct the trip->type == THERMAL_TRIP_HOT) continue; - fair_share_throttle(tz, trip, trip_level); + fair_share_throttle(tz, td, trip_level); } } Index: linux-pm/drivers/thermal/gov_power_allocator.c =================================================================== --- linux-pm.orig/drivers/thermal/gov_power_allocator.c +++ linux-pm/drivers/thermal/gov_power_allocator.c @@ -97,13 +97,6 @@ struct power_allocator_params { struct power_actor *power; }; -static bool power_actor_is_valid(struct power_allocator_params *params, - struct thermal_instance *instance) -{ - return (instance->trip == params->trip_max && - cdev_is_power_actor(instance->cdev)); -} - /** * estimate_sustainable_power() - Estimate the sustainable power of a thermal zone * @tz: thermal zone we are operating in @@ -118,13 +111,14 @@ static bool power_actor_is_valid(struct static u32 estimate_sustainable_power(struct thermal_zone_device *tz) { struct power_allocator_params *params = tz->governor_data; + const struct thermal_trip_desc *td = trip_to_trip_desc(params->trip_max); struct thermal_cooling_device *cdev; struct thermal_instance *instance; u32 sustainable_power = 0; u32 min_power; - list_for_each_entry(instance, &tz->thermal_instances, tz_node) { - if (!power_actor_is_valid(params, instance)) + list_for_each_entry(instance, &td->thermal_instances, trip_node) { + if (!cdev_is_power_actor(instance->cdev)) continue; cdev = instance->cdev; @@ -400,6 +394,7 @@ static void divvy_up_power(struct power_ static void allocate_power(struct thermal_zone_device *tz, int control_temp) { struct power_allocator_params *params = tz->governor_data; + const struct thermal_trip_desc *td = trip_to_trip_desc(params->trip_max); unsigned int num_actors = params->num_actors; struct power_actor *power = params->power; struct thermal_cooling_device *cdev; @@ -417,10 +412,10 @@ static void allocate_power(struct therma /* Clean all buffers for new power estimations */ memset(power, 0, params->buffer_size); - list_for_each_entry(instance, &tz->thermal_instances, tz_node) { + list_for_each_entry(instance, &td->thermal_instances, trip_node) { struct power_actor *pa = &power[i]; - if (!power_actor_is_valid(params, instance)) + if (!cdev_is_power_actor(instance->cdev)) continue; cdev = instance->cdev; @@ -454,10 +449,10 @@ static void allocate_power(struct therma power_range); i = 0; - list_for_each_entry(instance, &tz->thermal_instances, tz_node) { + list_for_each_entry(instance, &td->thermal_instances, trip_node) { struct power_actor *pa = &power[i]; - if (!power_actor_is_valid(params, instance)) + if (!cdev_is_power_actor(instance->cdev)) continue; power_actor_set_power(instance->cdev, instance, @@ -538,12 +533,13 @@ static void reset_pid_controller(struct static void allow_maximum_power(struct thermal_zone_device *tz) { struct power_allocator_params *params = tz->governor_data; + const struct thermal_trip_desc *td = trip_to_trip_desc(params->trip_max); struct thermal_cooling_device *cdev; struct thermal_instance *instance; u32 req_power; - list_for_each_entry(instance, &tz->thermal_instances, tz_node) { - if (!power_actor_is_valid(params, instance)) + list_for_each_entry(instance, &td->thermal_instances, trip_node) { + if (!cdev_is_power_actor(instance->cdev)) continue; cdev = instance->cdev; @@ -581,13 +577,11 @@ static void allow_maximum_power(struct t static int check_power_actors(struct thermal_zone_device *tz, struct power_allocator_params *params) { + const struct thermal_trip_desc *td = trip_to_trip_desc(params->trip_max); struct thermal_instance *instance; int ret = 0; - list_for_each_entry(instance, &tz->thermal_instances, tz_node) { - if (instance->trip != params->trip_max) - continue; - + list_for_each_entry(instance, &td->thermal_instances, trip_node) { if (!cdev_is_power_actor(instance->cdev)) { dev_warn(&tz->device, "power_allocator: %s is not a power actor\n", instance->cdev->type); @@ -635,14 +629,15 @@ static void power_allocator_update_tz(st enum thermal_notify_event reason) { struct power_allocator_params *params = tz->governor_data; + const struct thermal_trip_desc *td = trip_to_trip_desc(params->trip_max); struct thermal_instance *instance; int num_actors = 0; switch (reason) { case THERMAL_TZ_BIND_CDEV: case THERMAL_TZ_UNBIND_CDEV: - list_for_each_entry(instance, &tz->thermal_instances, tz_node) - if (power_actor_is_valid(params, instance)) + list_for_each_entry(instance, &td->thermal_instances, trip_node) + if (cdev_is_power_actor(instance->cdev)) num_actors++; if (num_actors == params->num_actors) @@ -652,8 +647,8 @@ static void power_allocator_update_tz(st break; case THERMAL_INSTANCE_WEIGHT_CHANGED: params->total_weight = 0; - list_for_each_entry(instance, &tz->thermal_instances, tz_node) - if (power_actor_is_valid(params, instance)) + list_for_each_entry(instance, &td->thermal_instances, trip_node) + if (cdev_is_power_actor(instance->cdev)) params->total_weight += instance->weight; break; default: Index: linux-pm/drivers/thermal/gov_step_wise.c =================================================================== --- linux-pm.orig/drivers/thermal/gov_step_wise.c +++ linux-pm/drivers/thermal/gov_step_wise.c @@ -66,9 +66,10 @@ static unsigned long get_target_state(st } static void thermal_zone_trip_update(struct thermal_zone_device *tz, - const struct thermal_trip *trip, + const struct thermal_trip_desc *td, int trip_threshold) { + const struct thermal_trip *trip = &td->trip; enum thermal_trend trend = get_tz_trend(tz, trip); int trip_id = thermal_zone_trip_id(tz, trip); struct thermal_instance *instance; @@ -82,12 +83,9 @@ static void thermal_zone_trip_update(str dev_dbg(&tz->device, "Trip%d[type=%d,temp=%d]:trend=%d,throttle=%d\n", trip_id, trip->type, trip_threshold, trend, throttle); - list_for_each_entry(instance, &tz->thermal_instances, tz_node) { + list_for_each_entry(instance, &td->thermal_instances, trip_node) { int old_target; - if (instance->trip != trip) - continue; - old_target = instance->target; instance->target = get_target_state(instance, trend, throttle); @@ -127,11 +125,13 @@ static void step_wise_manage(struct ther trip->type == THERMAL_TRIP_HOT) continue; - thermal_zone_trip_update(tz, trip, td->threshold); + thermal_zone_trip_update(tz, td, td->threshold); } - list_for_each_entry(instance, &tz->thermal_instances, tz_node) - thermal_cdev_update(instance->cdev); + for_each_trip_desc(tz, td) { + list_for_each_entry(instance, &td->thermal_instances, trip_node) + thermal_cdev_update(instance->cdev); + } } static struct thermal_governor thermal_gov_step_wise = { Index: linux-pm/drivers/thermal/thermal_helpers.c =================================================================== --- linux-pm.orig/drivers/thermal/thermal_helpers.c +++ linux-pm/drivers/thermal/thermal_helpers.c @@ -43,10 +43,11 @@ static bool thermal_instance_present(str struct thermal_cooling_device *cdev, const struct thermal_trip *trip) { + const struct thermal_trip_desc *td = trip_to_trip_desc(trip); struct thermal_instance *ti; - list_for_each_entry(ti, &tz->thermal_instances, tz_node) { - if (ti->trip == trip && ti->cdev == cdev) + list_for_each_entry(ti, &td->thermal_instances, trip_node) { + if (ti->cdev == cdev) return true; } From patchwork Tue Sep 10 09:28:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Rafael J. Wysocki" X-Patchwork-Id: 13798193 Received: from cloudserver094114.home.pl (cloudserver094114.home.pl [79.96.170.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 137A818C03F; Tue, 10 Sep 2024 09:43:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=79.96.170.134 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725961391; cv=none; b=YC5UuEYDeCquK/JGdnED4hHtV2CWip/v1CwUeFeB3OeGq7/4z5ayjmiSDsLlSrPpJrMleAIsHKXAlELnvPjInCBzmRrvbP+EC7+EeBHiqNX+w51RYmPstLzlbLmDb2yp+wYnZgDd1tIF/6o4RKNDYuae1KC4Gt4aQSS3Vfaj/rU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725961391; c=relaxed/simple; bh=tWC1x6kWLdZMv3C8z4KWP6WOlEn6zMSc5yL2vkwYUAQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Ll4ouDJHHFq1I2eYbuLZtmWxbpPsLWPGKHOblssgdSNyBIKL4CT2/r2awXXAsDSIKGa+HYN/ZX1ukZ7CEmSNKvnBDANi5K7wmumr5/y7eDxFpuz60vLBordLEBb2pu0d2NT8/Ott/bdZrEQxKuTrxhWiU+OCuh7IYCZj0qWjdPs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rjwysocki.net; spf=pass smtp.mailfrom=rjwysocki.net; dkim=fail (2048-bit key) header.d=rjwysocki.net header.i=@rjwysocki.net header.b=sjjzTC2q reason="signature verification failed"; arc=none smtp.client-ip=79.96.170.134 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rjwysocki.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rjwysocki.net Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=rjwysocki.net header.i=@rjwysocki.net header.b="sjjzTC2q" 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 6.2.0) id 190bcde46773db16; Tue, 10 Sep 2024 11:43:07 +0200 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 cloudserver094114.home.pl (Postfix) with ESMTPSA id 7B2646B836A; Tue, 10 Sep 2024 11:43:06 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=rjwysocki.net; s=dkim; t=1725961386; bh=tWC1x6kWLdZMv3C8z4KWP6WOlEn6zMSc5yL2vkwYUAQ=; h=From:Subject:Date; b=sjjzTC2qQI8rCtKLT55EKT9YuhwY/omE/1AjkTfU8OVCiq/WPGP2Y7weFu0vP1qbR 7qxlMP6m07yTcv0zg/iNui3E1L+sBoY9p+Mr/BoFFPhWs4pXTn+RssWADpKBXQiMyV 8sNKstI1Q1llvA733v9pkx6o924aZgELIJAfysFW8DQ5t96iVwQ0/5VPLp6xy4Q23q 41TvpB2oLHKtnXSvd6RxNk+cCwuMa9GlhIubDRNiT/MlP4RMHvVWlnsOak05NpE2S4 /Vr9u8mCR5sEfmUi1peS87pC+wM+//9Uq76xwtADpPNOpPCjbUIohvNJ3qn5EnhUUO SHCGRYoWk67Dw== From: "Rafael J. Wysocki" To: Linux PM Cc: LKML , Daniel Lezcano , Lukasz Luba , Zhang Rui Subject: [PATCH for 6.13 v1 2/8] thermal: core: Pass trip descriptors to trip bind/unbind functions Date: Tue, 10 Sep 2024 11:28:40 +0200 Message-ID: <2954063.e9J7NaK4W3@rjwysocki.net> In-Reply-To: <4920970.GXAFRqVoOG@rjwysocki.net> References: <4920970.GXAFRqVoOG@rjwysocki.net> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-CLIENT-IP: 195.136.19.94 X-CLIENT-HOSTNAME: 195.136.19.94 X-VADE-SPAMSTATE: spam:low X-VADE-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeftddrudeiledgudekucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecujffqoffgrffnpdggtffipffknecuuegrihhlohhuthemucduhedtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenogfuphgrmhfkphculdeftddtmdenucfjughrpefhvfevufffkfgjfhgggfgtsehtufertddttdejnecuhfhrohhmpedftfgrfhgrvghlucflrdcuhgihshhotghkihdfuceorhhjfiesrhhjfiihshhotghkihdrnhgvtheqnecuggftrfgrthhtvghrnhepvdffueeitdfgvddtudegueejtdffteetgeefkeffvdeftddttdeuhfegfedvjefhnecukfhppeduleehrddufeeirdduledrleegnecuufhprghmkfhppeduleehrddufeeirdduledrleegnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehinhgvthepudelhedrudefiedrudelrdelgedphhgvlhhopehkrhgvrggthhgvrhdrlhhotggrlhhnvghtpdhmrghilhhfrhhomheprhhjfiesrhhjfiihshhotghkihdrnhgvthdpnhgspghrtghpthhtohephedprhgtphhtthhopehlihhnuhigqdhpmhesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopehlihhnuhigqdhkvghrnhgvlhesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopegurghnihgvlhdrlhgviigtrghnoheslhhinhgrrhhordhorhhgpdhrtghpthhtoheplhhukhgrshiirdhluhgsrgesrghrmhdrtghomhdprhgtphhtthhopehruhhirdiihhgrnhhgsehinhhtvghlrdgtohhm X-DCC--Metrics: v370.home.net.pl 1024; Body=20 Fuz1=20 Fuz2=20 From: Rafael J. Wysocki Subject: [PATCH v3] The code is somewhat cleaner if struct thermal_trip_desc pointers are passed to thermal_bind_cdev_to_trip(), thermal_unbind_cdev_from_trip(), and print_bind_err_msg() instead of struct thermal_trip pointers, so modify it accordingly. No intentional functional impact. Signed-off-by: Rafael J. Wysocki --- drivers/thermal/thermal_core.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) Index: linux-pm/drivers/thermal/thermal_core.c =================================================================== --- linux-pm.orig/drivers/thermal/thermal_core.c +++ linux-pm/drivers/thermal/thermal_core.c @@ -754,9 +754,9 @@ struct thermal_zone_device *thermal_zone /** * thermal_bind_cdev_to_trip - bind a cooling device to a thermal zone * @tz: pointer to struct thermal_zone_device - * @trip: trip point the cooling devices is associated with in this zone. + * @td: descriptor of the trip point to bind @cdev to * @cdev: pointer to struct thermal_cooling_device - * @cool_spec: cooling specification for @trip and @cdev + * @cool_spec: cooling specification for the trip point and @cdev * * This interface function bind a thermal cooling device to the certain trip * point of a thermal zone device. @@ -765,11 +765,10 @@ struct thermal_zone_device *thermal_zone * Return: 0 on success, the proper error value otherwise. */ static int thermal_bind_cdev_to_trip(struct thermal_zone_device *tz, - struct thermal_trip *trip, + struct thermal_trip_desc *td, struct thermal_cooling_device *cdev, struct cooling_spec *cool_spec) { - struct thermal_trip_desc *td = trip_to_trip_desc(trip); struct thermal_instance *dev, *instance; bool upper_no_limit; int result; @@ -793,7 +792,7 @@ static int thermal_bind_cdev_to_trip(str return -ENOMEM; dev->cdev = cdev; - dev->trip = trip; + dev->trip = &td->trip; dev->upper = cool_spec->upper; dev->upper_no_limit = upper_no_limit; dev->lower = cool_spec->lower; @@ -865,7 +864,7 @@ free_mem: /** * thermal_unbind_cdev_from_trip - unbind a cooling device from a thermal zone. * @tz: pointer to a struct thermal_zone_device. - * @trip: trip point the cooling devices is associated with in this zone. + * @td: descriptor of the trip point to unbind @cdev from * @cdev: pointer to a struct thermal_cooling_device. * * This interface function unbind a thermal cooling device from the certain @@ -873,10 +872,9 @@ free_mem: * This function is usually called in the thermal zone device .unbind callback. */ static void thermal_unbind_cdev_from_trip(struct thermal_zone_device *tz, - struct thermal_trip *trip, + struct thermal_trip_desc *td, struct thermal_cooling_device *cdev) { - struct thermal_trip_desc *td = trip_to_trip_desc(trip); struct thermal_instance *pos, *next; mutex_lock(&cdev->lock); @@ -928,11 +926,11 @@ static struct class *thermal_class; static inline void print_bind_err_msg(struct thermal_zone_device *tz, - const struct thermal_trip *trip, + const struct thermal_trip_desc *td, struct thermal_cooling_device *cdev, int ret) { dev_err(&tz->device, "binding cdev %s to trip %d failed: %d\n", - cdev->type, thermal_zone_trip_id(tz, trip), ret); + cdev->type, thermal_zone_trip_id(tz, &td->trip), ret); } static void thermal_zone_cdev_bind(struct thermal_zone_device *tz, @@ -946,7 +944,6 @@ static void thermal_zone_cdev_bind(struc mutex_lock(&tz->lock); for_each_trip_desc(tz, td) { - struct thermal_trip *trip = &td->trip; struct cooling_spec c = { .upper = THERMAL_NO_LIMIT, .lower = THERMAL_NO_LIMIT, @@ -954,12 +951,12 @@ static void thermal_zone_cdev_bind(struc }; int ret; - if (!tz->ops.should_bind(tz, trip, cdev, &c)) + if (!tz->ops.should_bind(tz, &td->trip, cdev, &c)) continue; - ret = thermal_bind_cdev_to_trip(tz, trip, cdev, &c); + ret = thermal_bind_cdev_to_trip(tz, td, cdev, &c); if (ret) - print_bind_err_msg(tz, trip, cdev, ret); + print_bind_err_msg(tz, td, cdev, ret); } mutex_unlock(&tz->lock); @@ -1270,7 +1267,7 @@ static void thermal_zone_cdev_unbind(str mutex_lock(&tz->lock); for_each_trip_desc(tz, td) - thermal_unbind_cdev_from_trip(tz, &td->trip, cdev); + thermal_unbind_cdev_from_trip(tz, td, cdev); mutex_unlock(&tz->lock); } From patchwork Tue Sep 10 09:30:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Rafael J. Wysocki" X-Patchwork-Id: 13798188 Received: from cloudserver094114.home.pl (cloudserver094114.home.pl [79.96.170.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AEC331891A1; Tue, 10 Sep 2024 09:39:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=79.96.170.134 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725961168; cv=none; b=ECcMQE7kMddmAnikqmh6Qt4XQ3A1KQ+OhHOSM39n896j5sbe3a9OsIqwSq0TIXhQHnoZvvVZHmYYu+3OjdpvSW+BHbnnbtCRR4gzom/aTnUpS/1z6PQq9C/RiTUfPai0aGMe2DyQXSs9PNnpKxBmbhI4Ez3SANJu08vv2EfD/PY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725961168; c=relaxed/simple; bh=Uj/sl+T25qrRr38QlD3fqLUWWSOsn0W+6LPzNqo0/ZQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=s9a9uDr/fpP4W+Jh1RJG/Lb5oljJ9yARye8Kv+An5R7KVdlT9WmUcR2ju4+Jn/capB7pRk3JLn7ausX6Ud6vjZY77/FxaKvogFoHbryNYwT0XTbKE+ajsI+cSG5ME8h73eOABxu8AyTzuzotKtspWGjd6PjLcJfKs37QlU2KOg0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rjwysocki.net; spf=pass smtp.mailfrom=rjwysocki.net; dkim=fail (2048-bit key) header.d=rjwysocki.net header.i=@rjwysocki.net header.b=RCkOyiCk reason="signature verification failed"; arc=none smtp.client-ip=79.96.170.134 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rjwysocki.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rjwysocki.net Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=rjwysocki.net header.i=@rjwysocki.net header.b="RCkOyiCk" 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 6.2.0) id f9c7542ddd4df7b8; Tue, 10 Sep 2024 11:39:23 +0200 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 cloudserver094114.home.pl (Postfix) with ESMTPSA id 079806B836C; Tue, 10 Sep 2024 11:39:23 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=rjwysocki.net; s=dkim; t=1725961163; bh=Uj/sl+T25qrRr38QlD3fqLUWWSOsn0W+6LPzNqo0/ZQ=; h=From:Subject:Date; b=RCkOyiCklvWugGE3eGLg3GcDvW3YaZa7BJbjLnHkU+bn7C/zOLQIOES8gTLnmvu3Q iiqUEzcEUhJ37ajqv/20ymsSFAfo1wjPn0xRn/P/Gxch6D5pyTxCsmUjeQ8I+4jLhU E9Bnz7Q5ATUBgIfW9+wDeMTSA3jsEs5ZLaE3fHGLA6sfv+7aWr/e2ofArjzvoDrov1 v6yH3RUtdZO4r3Ri0n9tkfSEPQOYxnN8+USdX+Duz6Qesu4dbqzd/buw37CPmFeafZ SMboQ6GKploIhqok0M5mTF1RKbPXzdr8gUp5rQHsuKQW7lHvJ1ONV36qT7AfO8IHiY QGM0Ltt4BI3Qg== From: "Rafael J. Wysocki" To: Linux PM Cc: LKML , Daniel Lezcano , Lukasz Luba , Zhang Rui Subject: [PATCH for 6.13 v1 3/8] thermal: core: Build sorted lists instead of sorting them later Date: Tue, 10 Sep 2024 11:30:13 +0200 Message-ID: <3316488.44csPzL39Z@rjwysocki.net> In-Reply-To: <4920970.GXAFRqVoOG@rjwysocki.net> References: <4920970.GXAFRqVoOG@rjwysocki.net> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-CLIENT-IP: 195.136.19.94 X-CLIENT-HOSTNAME: 195.136.19.94 X-VADE-SPAMSTATE: spam:low X-VADE-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeftddrudeiledgudejucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecujffqoffgrffnpdggtffipffknecuuegrihhlohhuthemucduhedtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenogfuphgrmhfkphculdeftddtmdenucfjughrpefhvfevufffkfgjfhgggfgtsehtufertddttdejnecuhfhrohhmpedftfgrfhgrvghlucflrdcuhgihshhotghkihdfuceorhhjfiesrhhjfiihshhotghkihdrnhgvtheqnecuggftrfgrthhtvghrnhepvdffueeitdfgvddtudegueejtdffteetgeefkeffvdeftddttdeuhfegfedvjefhnecukfhppeduleehrddufeeirdduledrleegnecuufhprghmkfhppeduleehrddufeeirdduledrleegnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehinhgvthepudelhedrudefiedrudelrdelgedphhgvlhhopehkrhgvrggthhgvrhdrlhhotggrlhhnvghtpdhmrghilhhfrhhomheprhhjfiesrhhjfiihshhotghkihdrnhgvthdpnhgspghrtghpthhtohephedprhgtphhtthhopehlihhnuhigqdhpmhesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopehlihhnuhigqdhkvghrnhgvlhesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopegurghnihgvlhdrlhgviigtrghnoheslhhinhgrrhhordhorhhgpdhrtghpthhtoheplhhukhgrshiirdhluhgsrgesrghrmhdrtghomhdprhgtphhtthhopehruhhirdiihhgrnhhgsehinhhtvghlrdgtohhm X-DCC--Metrics: v370.home.net.pl 1024; Body=15 Fuz1=15 Fuz2=15 From: Rafael J. Wysocki Large numbers of trip points are not expected to be crossed in one go, so quite likely it is more efficient to build a sorted list of crossed trip points than to put them on an unsorted list and sort it later. Moreover, trip points are often provided in ascending temperature order during thermal zone registration. so they are naturally sorted anyway and building a sorted list out of them is quite straightforward. Accordingly, make handle_thermal_trip() maintain list ordering when adding trip points to the lists and get rid of separate list sorting in __thermal_zone_device_update(). No intentional functional impact. Signed-off-by: Rafael J. Wysocki --- drivers/thermal/thermal_core.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) Index: linux-pm/drivers/thermal/thermal_core.c =================================================================== --- linux-pm.orig/drivers/thermal/thermal_core.c +++ linux-pm/drivers/thermal/thermal_core.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -421,6 +420,21 @@ static void handle_critical_trips(struct tz->ops.hot(tz); } +static void add_trip_to_sorted_list(struct thermal_trip_desc *td, + struct list_head *list) +{ + struct thermal_trip_desc *entry; + + /* Assume that the new entry is likely to be the last one. */ + list_for_each_entry_reverse(entry, list, notify_list_node) { + if (entry->notify_temp <= td->notify_temp) { + list_add(&td->notify_list_node, &entry->notify_list_node); + return; + } + } + list_add(&td->notify_list_node, list); +} + static void handle_thermal_trip(struct thermal_zone_device *tz, struct thermal_trip_desc *td, struct list_head *way_up_list, @@ -450,8 +464,8 @@ static void handle_thermal_trip(struct t * In that case, the trip temperature becomes the new threshold. */ if (tz->temperature < trip->temperature - trip->hysteresis) { - list_add(&td->notify_list_node, way_down_list); td->notify_temp = trip->temperature - trip->hysteresis; + add_trip_to_sorted_list(td, way_down_list); if (trip->type == THERMAL_TRIP_PASSIVE) { tz->passive--; @@ -466,8 +480,9 @@ static void handle_thermal_trip(struct t * if the zone temperature exceeds the trip one. The new * threshold is then set to the low temperature of the trip. */ - list_add_tail(&td->notify_list_node, way_up_list); td->notify_temp = trip->temperature; + add_trip_to_sorted_list(td, way_up_list); + td->threshold -= trip->hysteresis; if (trip->type == THERMAL_TRIP_PASSIVE) @@ -531,16 +546,6 @@ static void thermal_trip_crossed(struct thermal_governor_trip_crossed(governor, tz, trip, crossed_up); } -static int thermal_trip_notify_cmp(void *not_used, const struct list_head *a, - const struct list_head *b) -{ - struct thermal_trip_desc *tda = container_of(a, struct thermal_trip_desc, - notify_list_node); - struct thermal_trip_desc *tdb = container_of(b, struct thermal_trip_desc, - notify_list_node); - return tda->notify_temp - tdb->notify_temp; -} - void __thermal_zone_device_update(struct thermal_zone_device *tz, enum thermal_notify_event event) { @@ -591,11 +596,9 @@ void __thermal_zone_device_update(struct thermal_zone_set_trips(tz, low, high); - list_sort(NULL, &way_up_list, thermal_trip_notify_cmp); list_for_each_entry(td, &way_up_list, notify_list_node) thermal_trip_crossed(tz, &td->trip, governor, true); - list_sort(NULL, &way_down_list, thermal_trip_notify_cmp); list_for_each_entry_reverse(td, &way_down_list, notify_list_node) thermal_trip_crossed(tz, &td->trip, governor, false); From patchwork Tue Sep 10 09:31:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Rafael J. Wysocki" X-Patchwork-Id: 13798187 Received: from cloudserver094114.home.pl (cloudserver094114.home.pl [79.96.170.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EAE9117BEAE; Tue, 10 Sep 2024 09:39:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=79.96.170.134 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725961168; cv=none; b=NdVlpk5HQaqbm300udGxJH+g0Q6k1TdUblkVLGGy+/mJ2oCTZfrfSV9owXqXJcEHuwECVish8l5X5tfvuRtFvrClawifRWYCqz1Eb5Gz1mampSpvQ7Di4Tf/z7HbfhaQ4u6y4I+OguXMFknA8Cu48M9T8exOd64DTKoK7k9G2n4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725961168; c=relaxed/simple; bh=RVPqfolybn6PJsOg3syy7Ov/xyNEtr+8kU/jK7GJ3+w=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=U9OxqmXeE4a6TTAbo82urpjdOfQr9tcPzRcSoOB7ucachswiDNTQ/R9RwFwehQtCjgpFIJcM1Q4uvyhNnxdo/E4weNyNJkaBZZ84b8S9cRubAJkesZLRg4flf0MYyV9mt+AJNzgPROd/HGXuU7Bb9GF28OCFsu+edtRkagOqA20= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rjwysocki.net; spf=pass smtp.mailfrom=rjwysocki.net; dkim=fail (2048-bit key) header.d=rjwysocki.net header.i=@rjwysocki.net header.b=iuHMvbTN reason="signature verification failed"; arc=none smtp.client-ip=79.96.170.134 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rjwysocki.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rjwysocki.net Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=rjwysocki.net header.i=@rjwysocki.net header.b="iuHMvbTN" 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 6.2.0) id 1c142ab01565bdd8; Tue, 10 Sep 2024 11:39:22 +0200 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 cloudserver094114.home.pl (Postfix) with ESMTPSA id 42CF46B836D; Tue, 10 Sep 2024 11:39:22 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=rjwysocki.net; s=dkim; t=1725961162; bh=RVPqfolybn6PJsOg3syy7Ov/xyNEtr+8kU/jK7GJ3+w=; h=From:Subject:Date; b=iuHMvbTNuiDWBsofV0qnE9bb9YYdzfrOO9c4f+7nbrDHRTRMVw6v5Vscl1FAQHqDt 4IY3Ms9F7l3eTvsywqG26NKuWJqcYKyGWT9dD3bsG0yRzWl0bwX2TOMHoSFrHZs5cr fiowAjxQCV4fZH+Esu5HnFFq1RmkQzO/c7QrBDhgf2Y/yTIgh2MdG7fa/F2nt3Ys2p Dpqxzhge0PiWtx5KryO5Q9W8gxaZkjgwXQpSkMCTaDnHSzYzFeKJkeMHwpMRKZMeUT pTGY6l7c2tBnH27BVg4E5+w900ENivf1J8tb6HZrhmrEpwCC6mX8KVG4FvPu1AOp4l c8RVsDnKIBgbw== From: "Rafael J. Wysocki" To: Linux PM Cc: LKML , Daniel Lezcano , Lukasz Luba , Zhang Rui Subject: [PATCH for 6.13 v1 4/8] thermal: core: Initialize thermal zones before registerimg them Date: Tue, 10 Sep 2024 11:31:19 +0200 Message-ID: <10527854.nUPlyArG6x@rjwysocki.net> In-Reply-To: <4920970.GXAFRqVoOG@rjwysocki.net> References: <4920970.GXAFRqVoOG@rjwysocki.net> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-CLIENT-IP: 195.136.19.94 X-CLIENT-HOSTNAME: 195.136.19.94 X-VADE-SPAMSTATE: spam:low X-VADE-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeftddrudeiledgudejucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecujffqoffgrffnpdggtffipffknecuuegrihhlohhuthemucduhedtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenogfuphgrmhfkphculdeftddtmdenucfjughrpefhvfevufffkfgjfhgggfgtsehtufertddttdejnecuhfhrohhmpedftfgrfhgrvghlucflrdcuhgihshhotghkihdfuceorhhjfiesrhhjfiihshhotghkihdrnhgvtheqnecuggftrfgrthhtvghrnhepvdffueeitdfgvddtudegueejtdffteetgeefkeffvdeftddttdeuhfegfedvjefhnecukfhppeduleehrddufeeirdduledrleegnecuufhprghmkfhppeduleehrddufeeirdduledrleegnecuvehluhhsthgvrhfuihiivgepvdenucfrrghrrghmpehinhgvthepudelhedrudefiedrudelrdelgedphhgvlhhopehkrhgvrggthhgvrhdrlhhotggrlhhnvghtpdhmrghilhhfrhhomheprhhjfiesrhhjfiihshhotghkihdrnhgvthdpnhgspghrtghpthhtohephedprhgtphhtthhopehlihhnuhigqdhpmhesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopehlihhnuhigqdhkvghrnhgvlhesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopegurghnihgvlhdrlhgviigtrghnoheslhhinhgrrhhordhorhhgpdhrtghpthhtoheplhhukhgrshiirdhluhgsrgesrghrmhdrtghomhdprhgtphhtthhopehruhhirdiihhgrnhhgsehinhhtvghlrdgtohhm X-DCC--Metrics: v370.home.net.pl 1024; Body=15 Fuz1=15 Fuz2=15 From: Rafael J. Wysocki Since user space can start interacting with a new thermal zone as soon as device_register() called by thermal_zone_device_register_with_trips() returns, it is better to initialize the thermal zone before calling device_register() on it. Signed-off-by: Rafael J. Wysocki --- drivers/thermal/thermal_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Index: linux-pm/drivers/thermal/thermal_core.c =================================================================== --- linux-pm.orig/drivers/thermal/thermal_core.c +++ linux-pm/drivers/thermal/thermal_core.c @@ -1469,6 +1469,7 @@ thermal_zone_device_register_with_trips( thermal_zone_destroy_device_groups(tz); goto remove_id; } + thermal_zone_device_init(tz); result = device_register(&tz->device); if (result) goto release_device; @@ -1507,7 +1508,6 @@ thermal_zone_device_register_with_trips( mutex_unlock(&thermal_list_lock); - thermal_zone_device_init(tz); /* Update the new thermal zone and mark it as already updated. */ if (atomic_cmpxchg(&tz->need_update, 1, 0)) thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED); From patchwork Tue Sep 10 09:32:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Rafael J. Wysocki" X-Patchwork-Id: 13798311 Received: from cloudserver094114.home.pl (cloudserver094114.home.pl [79.96.170.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E37E3194091; Tue, 10 Sep 2024 10:35:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=79.96.170.134 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725964546; cv=none; b=A4LqECgEDyl7H6MERmll7l1nj2ZC/xLKCEao6E+ZMHSetQ6qBC0a532uvbc1nRq+rnqUCjYG6ea8nOe01PbZIWfF3IHNXhPhhSmmegFW+po/U3VDS9Zs0eAguJ9ULhAHJVjF11jGoFcTGMc01BonTI7RZvKnR5fNXQQzsSTYDYM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725964546; c=relaxed/simple; bh=BFmiL4dTfjhPZodclFXsXNY9e9GWPt/7f2C7f21bUPw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Q2XHYKeEHei977rvb3xyIiwbgqdEm8Ltu9R/kDyZxWOgdMV1u5SC+WEb2JSoBb+kOPykfC8f2f6OT3wIYaKuHm5G8QpVO+V+VYF1gGpPbJ5uiRRNBqYzaN5LE2NXFpER3LQTFCDjGqGa9i5DumcLS6bCzl6+sYDwbN0jNRLGpGA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rjwysocki.net; spf=pass smtp.mailfrom=rjwysocki.net; dkim=fail (2048-bit key) header.d=rjwysocki.net header.i=@rjwysocki.net header.b=dD5Z2zPW reason="signature verification failed"; arc=none smtp.client-ip=79.96.170.134 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rjwysocki.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rjwysocki.net Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=rjwysocki.net header.i=@rjwysocki.net header.b="dD5Z2zPW" 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 6.2.0) id a006a526e2ca53cc; Tue, 10 Sep 2024 11:35:42 +0200 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 cloudserver094114.home.pl (Postfix) with ESMTPSA id 82EC46B836A; Tue, 10 Sep 2024 11:35:41 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=rjwysocki.net; s=dkim; t=1725960941; bh=BFmiL4dTfjhPZodclFXsXNY9e9GWPt/7f2C7f21bUPw=; h=From:Subject:Date; b=dD5Z2zPWRS4tv6EACgZN9J26dvmEX7T9DOGkntPCkseWCjrESwxvixNpM7TyxArF3 daPo653wQ0sNum3oCgMLJYI4mtbxERRO2XHzvtAlyfYceZ2dBR/ML1nKZeBg/K7WIx pFQHbaP4dn8GybCYZSSbgSVjk+ccQiynNumJXPGGjEhUPVr1o7Vm9i52u509QGzGqo fhQHwnAJ2fnMy1XmVAAALkcWHpFzhfL+Jv3sS2a3iMg1kDIec46XMu2ZyPZsDD3319 +he5BJF9n6HrO4JHf67E0q9CZbLBJvp+Lne/GC3SP8abxLKI5wfSlQ7t4CD2YaFblO kLlu50OvPjM/g== From: "Rafael J. Wysocki" To: Linux PM Cc: LKML , Daniel Lezcano , Lukasz Luba , Zhang Rui Subject: [PATCH for 6.13 v1 5/8] thermal: core: Rename trip list node in struct thermal_trip_desc Date: Tue, 10 Sep 2024 11:32:10 +0200 Message-ID: <1978487.PYKUYFuaPT@rjwysocki.net> In-Reply-To: <4920970.GXAFRqVoOG@rjwysocki.net> References: <4920970.GXAFRqVoOG@rjwysocki.net> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-CLIENT-IP: 195.136.19.94 X-CLIENT-HOSTNAME: 195.136.19.94 X-VADE-SPAMSTATE: spam:low X-VADE-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeftddrudeiledgudejucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecujffqoffgrffnpdggtffipffknecuuegrihhlohhuthemucduhedtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenogfuphgrmhfkphculdeftddtmdenucfjughrpefhvfevufffkfgjfhgggfgtsehtufertddttdejnecuhfhrohhmpedftfgrfhgrvghlucflrdcuhgihshhotghkihdfuceorhhjfiesrhhjfiihshhotghkihdrnhgvtheqnecuggftrfgrthhtvghrnhepvdffueeitdfgvddtudegueejtdffteetgeefkeffvdeftddttdeuhfegfedvjefhnecukfhppeduleehrddufeeirdduledrleegnecuufhprghmkfhppeduleehrddufeeirdduledrleegnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehinhgvthepudelhedrudefiedrudelrdelgedphhgvlhhopehkrhgvrggthhgvrhdrlhhotggrlhhnvghtpdhmrghilhhfrhhomheprhhjfiesrhhjfiihshhotghkihdrnhgvthdpnhgspghrtghpthhtohephedprhgtphhtthhopehlihhnuhigqdhpmhesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopehlihhnuhigqdhkvghrnhgvlhesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopegurghnihgvlhdrlhgviigtrghnoheslhhinhgrrhhordhorhhgpdhrtghpthhtoheplhhukhgrshiirdhluhgsrgesrghrmhdrtghomhdprhgtphhtthhopehruhhirdiihhgrnhhgsehinhhtvghlrdgtohhm X-DCC--Metrics: v370.home.net.pl 1024; Body=5 Fuz1=5 Fuz2=5 From: Rafael J. Wysocki Since the list node field in struct thermal_trip_desc is going to be used for purposes other than trip crossing notification, rename it to list_node. No intentional functional impact. Signed-off-by: Rafael J. Wysocki --- drivers/thermal/thermal_core.c | 10 +++++----- drivers/thermal/thermal_core.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) Index: linux-pm/drivers/thermal/thermal_core.c =================================================================== --- linux-pm.orig/drivers/thermal/thermal_core.c +++ linux-pm/drivers/thermal/thermal_core.c @@ -426,13 +426,13 @@ static void add_trip_to_sorted_list(stru struct thermal_trip_desc *entry; /* Assume that the new entry is likely to be the last one. */ - list_for_each_entry_reverse(entry, list, notify_list_node) { + list_for_each_entry_reverse(entry, list, list_node) { if (entry->notify_temp <= td->notify_temp) { - list_add(&td->notify_list_node, &entry->notify_list_node); + list_add(&td->list_node, &entry->list_node); return; } } - list_add(&td->notify_list_node, list); + list_add(&td->list_node, list); } static void handle_thermal_trip(struct thermal_zone_device *tz, @@ -596,10 +596,10 @@ void __thermal_zone_device_update(struct thermal_zone_set_trips(tz, low, high); - list_for_each_entry(td, &way_up_list, notify_list_node) + list_for_each_entry(td, &way_up_list, list_node) thermal_trip_crossed(tz, &td->trip, governor, true); - list_for_each_entry_reverse(td, &way_down_list, notify_list_node) + list_for_each_entry_reverse(td, &way_down_list, list_node) thermal_trip_crossed(tz, &td->trip, governor, false); if (governor->manage) Index: linux-pm/drivers/thermal/thermal_core.h =================================================================== --- linux-pm.orig/drivers/thermal/thermal_core.h +++ linux-pm/drivers/thermal/thermal_core.h @@ -29,7 +29,7 @@ struct thermal_trip_attrs { struct thermal_trip_desc { struct thermal_trip trip; struct thermal_trip_attrs trip_attrs; - struct list_head notify_list_node; + struct list_head list_node; struct list_head thermal_instances; int notify_temp; int threshold; From patchwork Tue Sep 10 09:33:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Rafael J. Wysocki" X-Patchwork-Id: 13798310 Received: from cloudserver094114.home.pl (cloudserver094114.home.pl [79.96.170.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E11D917B50F; Tue, 10 Sep 2024 10:35:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=79.96.170.134 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725964544; cv=none; b=isSOUurfmJ/6Yst06SocuNF28jUU9cMStIkfHkgCwZOfA/sfpFcsvBDZzQWF8Kr/oF0cyWypx22eYDznsdfnXy0qdh9KvOXjzqJt/gr8wQG9l+yuXdE/sEWCBVs+k56sHIzaUJ1/Z+NuXo6v2zBbgeb0mDDvfiu59me5wNhMw1g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725964544; c=relaxed/simple; bh=EjwxqU0E9VB+QozIQiYMMt3UTqBjXmxyMsecopMpiM4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=JEjpmG4DsfKApiRF1g2rIcNo8auLShFDPQR0z4SjChQCRncJUqXCWfo4ZeZ4dVuuvnazdNN4o0YNRLgsVxUBAhm2eyhl+bvkD/1LNvSB0WHp+JH45wyfwVax2LA16NDaT3jhlh2yIo5Qe5uMGJeRqpAo7FgxGMe0wxaDzWq+tfs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rjwysocki.net; spf=pass smtp.mailfrom=rjwysocki.net; dkim=fail (2048-bit key) header.d=rjwysocki.net header.i=@rjwysocki.net header.b=drATuo+1 reason="signature verification failed"; arc=none smtp.client-ip=79.96.170.134 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rjwysocki.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rjwysocki.net Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=rjwysocki.net header.i=@rjwysocki.net header.b="drATuo+1" 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 6.2.0) id 13f8732939dc558d; Tue, 10 Sep 2024 11:35:40 +0200 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 cloudserver094114.home.pl (Postfix) with ESMTPSA id 297646B836A; Tue, 10 Sep 2024 11:35:40 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=rjwysocki.net; s=dkim; t=1725960940; bh=EjwxqU0E9VB+QozIQiYMMt3UTqBjXmxyMsecopMpiM4=; h=From:Subject:Date; b=drATuo+1gRCRizsT/9T1WUeJ35N1sKCStaq4DtL/DKMtsHzDi1ySXrmqgKa+Ja1bC 18G4GQHEo74PYvGWIDpuQSGGOqR7BsIs0xRJ+GUFf36KlzPNOXnP/7BUTYCk14BiDf ZmAn2SLXRBz0WYhIQ/gg6Vgs9gfligOnqlCINcJOdqUfRdo+NjQCz7aL+vv2Odom6G 3k/F40KDZOHstecf3texTJhF+ob2KVwpalrEzXg3taBVMxZDwhEmlHOB1cHFaX3C+K Fcz6INY43B34QPfogaLd81olhh2mxmzD4t2bC/nfhjbf9IxEZmagqLWPLjLCkY4FLz PYFAaVmauf2lQ== From: "Rafael J. Wysocki" To: Linux PM Cc: LKML , Daniel Lezcano , Lukasz Luba , Zhang Rui Subject: [PATCH for 6.13 v1 6/8] thermal: core: Add function for moving trips to sorted lists Date: Tue, 10 Sep 2024 11:33:08 +0200 Message-ID: <7708886.EvYhyI6sBW@rjwysocki.net> In-Reply-To: <4920970.GXAFRqVoOG@rjwysocki.net> References: <4920970.GXAFRqVoOG@rjwysocki.net> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-CLIENT-IP: 195.136.19.94 X-CLIENT-HOSTNAME: 195.136.19.94 X-VADE-SPAMSTATE: spam:low X-VADE-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeftddrudeiledgudejucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecujffqoffgrffnpdggtffipffknecuuegrihhlohhuthemucduhedtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenogfuphgrmhfkphculdeftddtmdenucfjughrpefhvfevufffkfgjfhgggfgtsehtufertddttdejnecuhfhrohhmpedftfgrfhgrvghlucflrdcuhgihshhotghkihdfuceorhhjfiesrhhjfiihshhotghkihdrnhgvtheqnecuggftrfgrthhtvghrnhepvdffueeitdfgvddtudegueejtdffteetgeefkeffvdeftddttdeuhfegfedvjefhnecukfhppeduleehrddufeeirdduledrleegnecuufhprghmkfhppeduleehrddufeeirdduledrleegnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehinhgvthepudelhedrudefiedrudelrdelgedphhgvlhhopehkrhgvrggthhgvrhdrlhhotggrlhhnvghtpdhmrghilhhfrhhomheprhhjfiesrhhjfiihshhotghkihdrnhgvthdpnhgspghrtghpthhtohephedprhgtphhtthhopehlihhnuhigqdhpmhesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopehlihhnuhigqdhkvghrnhgvlhesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopegurghnihgvlhdrlhgviigtrghnoheslhhinhgrrhhordhorhhgpdhrtghpthhtoheplhhukhgrshiirdhluhgsrgesrghrmhdrtghomhdprhgtphhtthhopehruhhirdiihhgrnhhgsehinhhtvghlrdgtohhm X-DCC--Metrics: v370.home.net.pl 1024; Body=5 Fuz1=5 Fuz2=5 From: Rafael J. Wysocki Subsequently, trips will be moved between sorted lists in multiple places, so replace add_trip_to_sorted_list() with an analogous function that will move a given trip to a given sorted list. Call the new function thermal_trip_move_to_sorted_list() and put it into the trips-related part of the code. To allow list_move() used in the new function to work, initialize the list_node fields of trip descriptors so they are always valid. No intentional functional impact. Signed-off-by: Rafael J. Wysocki --- drivers/thermal/thermal_core.c | 30 ++++++++++-------------------- drivers/thermal/thermal_core.h | 2 ++ drivers/thermal/thermal_trip.c | 15 +++++++++++++++ 3 files changed, 27 insertions(+), 20 deletions(-) Index: linux-pm/drivers/thermal/thermal_core.c =================================================================== --- linux-pm.orig/drivers/thermal/thermal_core.c +++ linux-pm/drivers/thermal/thermal_core.c @@ -420,21 +420,6 @@ static void handle_critical_trips(struct tz->ops.hot(tz); } -static void add_trip_to_sorted_list(struct thermal_trip_desc *td, - struct list_head *list) -{ - struct thermal_trip_desc *entry; - - /* Assume that the new entry is likely to be the last one. */ - list_for_each_entry_reverse(entry, list, list_node) { - if (entry->notify_temp <= td->notify_temp) { - list_add(&td->list_node, &entry->list_node); - return; - } - } - list_add(&td->list_node, list); -} - static void handle_thermal_trip(struct thermal_zone_device *tz, struct thermal_trip_desc *td, struct list_head *way_up_list, @@ -465,7 +450,7 @@ static void handle_thermal_trip(struct t */ if (tz->temperature < trip->temperature - trip->hysteresis) { td->notify_temp = trip->temperature - trip->hysteresis; - add_trip_to_sorted_list(td, way_down_list); + thermal_trip_move_to_sorted_list(td, way_down_list); if (trip->type == THERMAL_TRIP_PASSIVE) { tz->passive--; @@ -481,7 +466,7 @@ static void handle_thermal_trip(struct t * threshold is then set to the low temperature of the trip. */ td->notify_temp = trip->temperature; - add_trip_to_sorted_list(td, way_up_list); + thermal_trip_move_to_sorted_list(td, way_up_list); td->threshold -= trip->hysteresis; @@ -550,7 +535,7 @@ void __thermal_zone_device_update(struct enum thermal_notify_event event) { struct thermal_governor *governor = thermal_get_tz_governor(tz); - struct thermal_trip_desc *td; + struct thermal_trip_desc *td, *next; LIST_HEAD(way_down_list); LIST_HEAD(way_up_list); int low = -INT_MAX, high = INT_MAX; @@ -596,11 +581,15 @@ void __thermal_zone_device_update(struct thermal_zone_set_trips(tz, low, high); - list_for_each_entry(td, &way_up_list, list_node) + list_for_each_entry_safe(td, next, &way_up_list, list_node) { thermal_trip_crossed(tz, &td->trip, governor, true); + list_del_init(&td->list_node); + } - list_for_each_entry_reverse(td, &way_down_list, list_node) + list_for_each_entry_safe_reverse(td, next, &way_down_list, list_node) { thermal_trip_crossed(tz, &td->trip, governor, false); + list_del_init(&td->list_node); + } if (governor->manage) governor->manage(tz); @@ -1443,6 +1432,7 @@ thermal_zone_device_register_with_trips( for_each_trip_desc(tz, td) { td->trip = *trip++; INIT_LIST_HEAD(&td->thermal_instances); + INIT_LIST_HEAD(&td->list_node); /* * Mark all thresholds as invalid to start with even though * this only matters for the trips that start as invalid and Index: linux-pm/drivers/thermal/thermal_core.h =================================================================== --- linux-pm.orig/drivers/thermal/thermal_core.h +++ linux-pm/drivers/thermal/thermal_core.h @@ -256,6 +256,8 @@ const char *thermal_trip_type_name(enum void thermal_zone_set_trips(struct thermal_zone_device *tz, int low, int high); int thermal_zone_trip_id(const struct thermal_zone_device *tz, const struct thermal_trip *trip); +void thermal_trip_move_to_sorted_list(struct thermal_trip_desc *td, + struct list_head *list); int __thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp); void thermal_zone_trip_down(struct thermal_zone_device *tz, const struct thermal_trip *trip); Index: linux-pm/drivers/thermal/thermal_trip.c =================================================================== --- linux-pm.orig/drivers/thermal/thermal_trip.c +++ linux-pm/drivers/thermal/thermal_trip.c @@ -93,6 +93,21 @@ int thermal_zone_trip_id(const struct th return trip_to_trip_desc(trip) - tz->trips; } +void thermal_trip_move_to_sorted_list(struct thermal_trip_desc *td, + struct list_head *list) +{ + struct thermal_trip_desc *entry; + + /* Assume that the new entry is likely to be the last one. */ + list_for_each_entry_reverse(entry, list, list_node) { + if (entry->notify_temp <= td->notify_temp) { + list_move(&td->list_node, &entry->list_node); + return; + } + } + list_move(&td->list_node, list); +} + void thermal_zone_set_trip_hyst(struct thermal_zone_device *tz, struct thermal_trip *trip, int hyst) { From patchwork Tue Sep 10 09:34:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Rafael J. Wysocki" X-Patchwork-Id: 13798309 Received: from cloudserver094114.home.pl (cloudserver094114.home.pl [79.96.170.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 541D8194080; Tue, 10 Sep 2024 10:35:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=79.96.170.134 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725964544; cv=none; b=gTXN0qpg7qHJODTg6/niYrb9YBX1WbH8vEMFeugZq8pTnW/HK887qBLzQb1knoF8gKwImnkrne+WtxxF+ziz9b2Icn9ZLvUJTCOtaX7SmHvxjgAkHDDP9QwPqwiGYzMVN+0Iq1LoSuJcW7h4yxDVcJchl2nbs3xVk0EhFuzXU0Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725964544; c=relaxed/simple; bh=1lMwBCl9f+Yjv3w/UaM4GEROEvfctQuREDnQV9MTNLM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=VY6bsSX94srQMWOh9jLTeDuDbGgCpuQqXqvzpmU79Ma+zL9PxRcPHWW6aMnYAbwXuvqbZUdbaEbB84PmNguGxV0TX0A59nyUwySW1Lx4K7qgc+TZ/Ja3UKJs9pImRWoAhJwugwPZZ/mw4lmBMExaeHwGBPvn8qO09IzagGmIgbs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rjwysocki.net; spf=pass smtp.mailfrom=rjwysocki.net; dkim=fail (2048-bit key) header.d=rjwysocki.net header.i=@rjwysocki.net header.b=fQeQ0hhn reason="signature verification failed"; arc=none smtp.client-ip=79.96.170.134 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rjwysocki.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rjwysocki.net Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=rjwysocki.net header.i=@rjwysocki.net header.b="fQeQ0hhn" 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 6.2.0) id 10e21e6ff6389992; Tue, 10 Sep 2024 11:35:39 +0200 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 cloudserver094114.home.pl (Postfix) with ESMTPSA id 5508B6B836A; Tue, 10 Sep 2024 11:35:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=rjwysocki.net; s=dkim; t=1725960939; bh=1lMwBCl9f+Yjv3w/UaM4GEROEvfctQuREDnQV9MTNLM=; h=From:Subject:Date; b=fQeQ0hhnp7iG5PcUOPX9EbFFM0IPZEOWyZYW9EKDPrg65icq5FyjWjUjPItEb6JaB hRsiEKVQPUMgfWSYg4ojubu1/djC6qrwo2eUCJaYdCz73c+iUthdSHZ1nP+F3SOuAq +US7NHesbssyTX2elZEPw9RGIByIkTWXA/zKkkN5uuAksZ2R1CsbyOupgOGHc3zJec I4cdBAUUtCQjNyqbCc3quknQHyHkEUwRztBTG3+ryVyPc/RTIdlPEhqPQuJNimgqpA BEr4YS+7Mq4SoNrFRCZTdP/TRXnikSZKMg5UaOppx/CBLtznZxHLxVD7WsBC1/kUVJ M6AiL5PzGQrwA== From: "Rafael J. Wysocki" To: Linux PM Cc: LKML , Daniel Lezcano , Lukasz Luba , Zhang Rui Subject: [PATCH for 6.13 v1 7/8] thermal: core: Use trip lists for trip crossing detection Date: Tue, 10 Sep 2024 11:34:29 +0200 Message-ID: <3584535.iIbC2pHGDl@rjwysocki.net> In-Reply-To: <4920970.GXAFRqVoOG@rjwysocki.net> References: <4920970.GXAFRqVoOG@rjwysocki.net> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-CLIENT-IP: 195.136.19.94 X-CLIENT-HOSTNAME: 195.136.19.94 X-VADE-SPAMSTATE: spam:low X-VADE-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeftddrudeiledgudeiucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecujffqoffgrffnpdggtffipffknecuuegrihhlohhuthemucduhedtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenogfuphgrmhfkphculdeftddtmdenucfjughrpefhvfevufffkfgjfhgggfgtsehtufertddttdejnecuhfhrohhmpedftfgrfhgrvghlucflrdcuhgihshhotghkihdfuceorhhjfiesrhhjfiihshhotghkihdrnhgvtheqnecuggftrfgrthhtvghrnhepvdffueeitdfgvddtudegueejtdffteetgeefkeffvdeftddttdeuhfegfedvjefhnecukfhppeduleehrddufeeirdduledrleegnecuufhprghmkfhppeduleehrddufeeirdduledrleegnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehinhgvthepudelhedrudefiedrudelrdelgedphhgvlhhopehkrhgvrggthhgvrhdrlhhotggrlhhnvghtpdhmrghilhhfrhhomheprhhjfiesrhhjfiihshhotghkihdrnhgvthdpnhgspghrtghpthhtohephedprhgtphhtthhopehlihhnuhigqdhpmhesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopehlihhnuhigqdhkvghrnhgvlhesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopegurghnihgvlhdrlhgviigtrghnoheslhhinhgrrhhordhorhhgpdhrtghpthhtoheplhhukhgrshiirdhluhgsrgesrghrmhdrtghomhdprhgtphhtthhopehruhhirdiihhgrnhhgsehinhhtvghlrdgtohhm X-DCC--Metrics: v370.home.net.pl 1024; Body=5 Fuz1=5 Fuz2=5 From: Rafael J. Wysocki Modify the thermal core to use three lists of trip points: trips_above containing trips with thresholds strictly above the current thermal zone temperature, trips_below containing trips with thresholds at or below the current zone temperature, trips_invalid containing trips with temperature equal to THERMAL_ZONE_INVALID, where the first two lists are always sorted. For each trip in trips_above, there is no mitigation under way and the trip threshold is equal to its temperature. In turn, for each trip in trips_below, there is mitigation under way and the trip threshold is equal to its low temperature. The trips in trips_invalid, of course, need not be taken into consideration. The idea is to make __thermal_zone_device_update() walk trips_above and trips_below instead of walking the entire table of trip points in the thermal zone. Usually, it will only need to walk a few entries in one of the lists and check one entry in the other one, depending on the direction of the zone temperature changes, because crossing many trips by the zone temperature in one go between two consecutive temperature checks should be unlikely (if this happens, the thermal zone temperature is checked too rarely or not at the right time). Moreover, because the lists are sorted, the low and high values needed by thermal_zone_set_trips() can be determined in a straightforward way by looking at one end of each list. Of course, additional work is needed in some places in order to maintain the ordering of the lists, but it happens in situations that should be rare, like updating a trip point temperature or hysteresis, at the thermal zone initialization time or during system resume. Going forward, the trips_below and trips_above lists can be used by thermal governors to reduce overhead. Signed-off-by: Rafael J. Wysocki --- drivers/thermal/thermal_core.c | 150 ++++++++++++++++++++--------------------- drivers/thermal/thermal_core.h | 7 + drivers/thermal/thermal_trip.c | 69 +++++++++++++----- 3 files changed, 132 insertions(+), 94 deletions(-) Index: linux-pm/drivers/thermal/thermal_core.c =================================================================== --- linux-pm.orig/drivers/thermal/thermal_core.c +++ linux-pm/drivers/thermal/thermal_core.c @@ -420,64 +420,6 @@ static void handle_critical_trips(struct tz->ops.hot(tz); } -static void handle_thermal_trip(struct thermal_zone_device *tz, - struct thermal_trip_desc *td, - struct list_head *way_up_list, - struct list_head *way_down_list) -{ - const struct thermal_trip *trip = &td->trip; - int old_threshold; - - if (trip->temperature == THERMAL_TEMP_INVALID) - return; - - /* - * If the trip temperature or hysteresis has been updated recently, - * the threshold needs to be computed again using the new values. - * However, its initial value still reflects the old ones and that - * is what needs to be compared with the previous zone temperature - * to decide which action to take. - */ - old_threshold = td->threshold; - td->threshold = trip->temperature; - - if (tz->last_temperature >= old_threshold && - tz->last_temperature != THERMAL_TEMP_INIT) { - /* - * Mitigation is under way, so it needs to stop if the zone - * temperature falls below the low temperature of the trip. - * In that case, the trip temperature becomes the new threshold. - */ - if (tz->temperature < trip->temperature - trip->hysteresis) { - td->notify_temp = trip->temperature - trip->hysteresis; - thermal_trip_move_to_sorted_list(td, way_down_list); - - if (trip->type == THERMAL_TRIP_PASSIVE) { - tz->passive--; - WARN_ON(tz->passive < 0); - } - } else { - td->threshold -= trip->hysteresis; - } - } else if (tz->temperature >= trip->temperature) { - /* - * There is no mitigation under way, so it needs to be started - * if the zone temperature exceeds the trip one. The new - * threshold is then set to the low temperature of the trip. - */ - td->notify_temp = trip->temperature; - thermal_trip_move_to_sorted_list(td, way_up_list); - - td->threshold -= trip->hysteresis; - - if (trip->type == THERMAL_TRIP_PASSIVE) - tz->passive++; - else if (trip->type == THERMAL_TRIP_CRITICAL || - trip->type == THERMAL_TRIP_HOT) - handle_critical_trips(tz, trip); - } -} - static void thermal_zone_device_check(struct work_struct *work) { struct thermal_zone_device *tz = container_of(work, struct @@ -486,9 +428,16 @@ static void thermal_zone_device_check(st thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED); } +static void move_trip_to_trips_above(struct thermal_trip_desc *td, + struct thermal_zone_device *tz) +{ + td->threshold = td->trip.temperature; + thermal_trip_move_to_sorted_list(td, &tz->trips_above); +} + static void thermal_zone_device_init(struct thermal_zone_device *tz) { - struct thermal_trip_desc *td; + struct thermal_trip_desc *td, *next; INIT_DELAYED_WORK(&tz->poll_queue, thermal_zone_device_check); @@ -502,6 +451,16 @@ static void thermal_zone_device_init(str list_for_each_entry(instance, &td->thermal_instances, trip_node) instance->initialized = false; } + list_for_each_entry_safe(td, next, &tz->trips_invalid, list_node) { + if (td->trip.temperature != THERMAL_TEMP_INVALID) + move_trip_to_trips_above(td, tz); + } + list_for_each_entry_safe(td, next, &tz->trips_below, list_node) { + if (td->trip.temperature == THERMAL_TEMP_INVALID) + list_move(&td->list_node, &tz->trips_invalid); + else + move_trip_to_trips_above(td, tz); + } } static void thermal_governor_trip_crossed(struct thermal_governor *governor, @@ -569,27 +528,71 @@ void __thermal_zone_device_update(struct tz->notify_event = event; - for_each_trip_desc(tz, td) { - handle_thermal_trip(tz, td, &way_up_list, &way_down_list); + /* Check trips that were previously above the zone temperature. */ + list_for_each_entry_safe(td, next, &tz->trips_above, list_node) { + struct thermal_trip *trip = &td->trip; - if (td->threshold <= tz->temperature && td->threshold > low) - low = td->threshold; + if (td->threshold > tz->temperature) + break; + + /* + * There is no mitigation under way, so it needs to be started. + * Move the trip to the "crossed on the way up" list (sorted by + * the old threshold) and set the new threshold to the low + * temperature of the trip. + */ + thermal_trip_move_to_sorted_list(td, &way_up_list); + td->threshold = trip->temperature - trip->hysteresis; - if (td->threshold >= tz->temperature && td->threshold < high) - high = td->threshold; + if (trip->type == THERMAL_TRIP_PASSIVE) + tz->passive++; + else if (trip->type == THERMAL_TRIP_CRITICAL || + trip->type == THERMAL_TRIP_HOT) + handle_critical_trips(tz, trip); } + /* Check trips that were previously below or at the zone temperature. */ + list_for_each_entry_safe_reverse(td, next, &tz->trips_below, list_node) { + struct thermal_trip *trip = &td->trip; - thermal_zone_set_trips(tz, low, high); + if (td->threshold <= tz->temperature) + break; + + /* + * Mitigation is under way, so it needs to stop. Move the trip + * to the "crossed on the way down" list (sorted by the old + * threshold) and set the new threshold to the trip temperature. + */ + thermal_trip_move_to_sorted_list(td, &way_down_list); + td->threshold = trip->temperature; + + if (trip->type == THERMAL_TRIP_PASSIVE) { + tz->passive--; + WARN_ON(tz->passive < 0); + } + } list_for_each_entry_safe(td, next, &way_up_list, list_node) { thermal_trip_crossed(tz, &td->trip, governor, true); - list_del_init(&td->list_node); + thermal_trip_move_to_sorted_list(td, &tz->trips_below); } list_for_each_entry_safe_reverse(td, next, &way_down_list, list_node) { thermal_trip_crossed(tz, &td->trip, governor, false); - list_del_init(&td->list_node); + thermal_trip_move_to_sorted_list(td, &tz->trips_above); + } + + if (!list_empty(&tz->trips_below)) { + td = list_last_entry(&tz->trips_below, struct thermal_trip_desc, + list_node); + /* Avoid checks that don't correspond to trip crossing. */ + low = td->threshold - 1; + } + if (!list_empty(&tz->trips_above)) { + td = list_first_entry(&tz->trips_above, struct thermal_trip_desc, + list_node); + high = td->threshold; } + thermal_zone_set_trips(tz, low, high); if (governor->manage) governor->manage(tz); @@ -1409,6 +1412,9 @@ thermal_zone_device_register_with_trips( } INIT_LIST_HEAD(&tz->node); + INIT_LIST_HEAD(&tz->trips_above); + INIT_LIST_HEAD(&tz->trips_below); + INIT_LIST_HEAD(&tz->trips_invalid); ida_init(&tz->ida); mutex_init(&tz->lock); init_completion(&tz->removal); @@ -1432,13 +1438,7 @@ thermal_zone_device_register_with_trips( for_each_trip_desc(tz, td) { td->trip = *trip++; INIT_LIST_HEAD(&td->thermal_instances); - INIT_LIST_HEAD(&td->list_node); - /* - * Mark all thresholds as invalid to start with even though - * this only matters for the trips that start as invalid and - * become valid later. - */ - td->threshold = INT_MAX; + list_add(&td->list_node, &tz->trips_invalid); } tz->polling_delay_jiffies = msecs_to_jiffies(polling_delay); Index: linux-pm/drivers/thermal/thermal_core.h =================================================================== --- linux-pm.orig/drivers/thermal/thermal_core.h +++ linux-pm/drivers/thermal/thermal_core.h @@ -31,7 +31,6 @@ struct thermal_trip_desc { struct thermal_trip_attrs trip_attrs; struct list_head list_node; struct list_head thermal_instances; - int notify_temp; int threshold; }; @@ -69,6 +68,9 @@ struct thermal_governor { * @device: &struct device for this thermal zone * @removal: removal completion * @resume: resume completion + * @trips_above: trips above the current zone temperature + * @trips_below: trips equal to or below the current zone temperature + * @trips_invalid: trips with invalid temperature * @mode: current mode of this thermal zone * @devdata: private pointer for device private data * @num_trips: number of trip points the thermal zone supports @@ -111,6 +113,9 @@ struct thermal_zone_device { struct completion removal; struct completion resume; struct attribute_group trips_attribute_group; + struct list_head trips_above; + struct list_head trips_below; + struct list_head trips_invalid; enum thermal_device_mode mode; void *devdata; int num_trips; Index: linux-pm/drivers/thermal/thermal_trip.c =================================================================== --- linux-pm.orig/drivers/thermal/thermal_trip.c +++ linux-pm/drivers/thermal/thermal_trip.c @@ -100,7 +100,7 @@ void thermal_trip_move_to_sorted_list(st /* Assume that the new entry is likely to be the last one. */ list_for_each_entry_reverse(entry, list, list_node) { - if (entry->notify_temp <= td->notify_temp) { + if (entry->threshold <= td->threshold) { list_move(&td->list_node, &entry->list_node); return; } @@ -111,39 +111,72 @@ void thermal_trip_move_to_sorted_list(st void thermal_zone_set_trip_hyst(struct thermal_zone_device *tz, struct thermal_trip *trip, int hyst) { + struct thermal_trip_desc *td = trip_to_trip_desc(trip); + WRITE_ONCE(trip->hysteresis, hyst); thermal_notify_tz_trip_change(tz, trip); + if (tz->temperature >= td->threshold) { + /* + * The zone temperature was above or at the trip, so the trip's + * new threshold should be equal to its low temperature. + */ + td->threshold = trip->temperature - hyst; + thermal_trip_move_to_sorted_list(td, &tz->trips_below); + } } void thermal_zone_set_trip_temp(struct thermal_zone_device *tz, struct thermal_trip *trip, int temp) { + struct thermal_trip_desc *td = trip_to_trip_desc(trip); + struct list_head *list; + if (trip->temperature == temp) return; + if (trip->temperature == THERMAL_TEMP_INVALID) { + td->threshold = temp; + /* + * Move the trip to the "trips above" list regardless of the new + * temperature value because there is no mitigation going on for + * it. If mitigation needs to be started, it will be moved to + * the "trips below" list later. + */ + thermal_trip_move_to_sorted_list(td, &tz->trips_above); + list = NULL; + } else if (tz->temperature >= td->threshold) { + /* The trip's threshold was below the zone temperature */ + td->threshold = temp - trip->hysteresis; + list = &tz->trips_below; + } else { + /* The trip's threshold was above the zone temperature */ + td->threshold = temp; + list = &tz->trips_above; + } + WRITE_ONCE(trip->temperature, temp); thermal_notify_tz_trip_change(tz, trip); - if (temp == THERMAL_TEMP_INVALID) { - struct thermal_trip_desc *td = trip_to_trip_desc(trip); + if (!list) + return; - if (tz->temperature >= td->threshold) { - /* - * The trip has been crossed on the way up, so some - * adjustments are needed to compensate for the lack - * of it going forward. - */ - if (trip->type == THERMAL_TRIP_PASSIVE) { - tz->passive--; - WARN_ON_ONCE(tz->passive < 0); - } - thermal_zone_trip_down(tz, trip); - } + if (temp != THERMAL_TEMP_INVALID) { + thermal_trip_move_to_sorted_list(td, list); + return; + } + + if (tz->temperature >= td->threshold) { /* - * Invalidate the threshold to avoid triggering a spurious - * trip crossing notification when the trip becomes valid. + * The zone temperature was at or above the trip, so some + * adjustments are needed to compensate for the lack of it + * going forward. */ - td->threshold = INT_MAX; + if (trip->type == THERMAL_TRIP_PASSIVE) { + tz->passive--; + WARN_ON_ONCE(tz->passive < 0); + } + thermal_zone_trip_down(tz, trip); } + list_move(&td->list_node, &tz->trips_invalid); } EXPORT_SYMBOL_GPL(thermal_zone_set_trip_temp); From patchwork Tue Sep 10 09:35:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Rafael J. Wysocki" X-Patchwork-Id: 13798308 Received: from cloudserver094114.home.pl (cloudserver094114.home.pl [79.96.170.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DECE7193439; Tue, 10 Sep 2024 10:35:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=79.96.170.134 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725964543; cv=none; b=TxBfKugHrgjVLlR2uOH2L8R4C4j4gFqOsjZv4mszMPGAmGEal59DoXeCddxvr6H76E2Mdo3VR+xrc/OS7YULHr9R63WpYy2ODAcvwfozY08DDWa4Llxk601jAh1XWEZv7+xVOcSHfWte4yVAp8QLn+rLhcZJ5tAeqJe7RiD3fGU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725964543; c=relaxed/simple; bh=u/7UB3Q5cuqzEscCukI5NdFR2SsbxTFB4sY1UpEhUAM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ONpzIRXtCNGVlkHY7E81Kl0TRANrPn262UwA0xJQjqus8+WDzhcU9XhryNntk4xUYwSlxrq5UZngDpozUM1Ia8r7wcyqmBe4i8I2p0SxUxOBxeRjCYEtMIZ9yiZAPHyvlo+j+GpNSNl14sr8honSAomQ8JJGaI+zxURfN9cEY/o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rjwysocki.net; spf=pass smtp.mailfrom=rjwysocki.net; dkim=pass (2048-bit key) header.d=rjwysocki.net header.i=@rjwysocki.net header.b=ifRnyhV+; arc=none smtp.client-ip=79.96.170.134 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rjwysocki.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rjwysocki.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=rjwysocki.net header.i=@rjwysocki.net header.b="ifRnyhV+" 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 6.2.0) id 113eee69d23d6f90; Tue, 10 Sep 2024 11:35:38 +0200 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 cloudserver094114.home.pl (Postfix) with ESMTPSA id 6D3C46B836C; Tue, 10 Sep 2024 11:35:38 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=rjwysocki.net; s=dkim; t=1725960938; bh=u/7UB3Q5cuqzEscCukI5NdFR2SsbxTFB4sY1UpEhUAM=; h=From:Subject:Date; b=ifRnyhV+yIjoHdrIahCzt6HEJxoSqk+B7P84qoPHeKZOSrwi7c1K4ByDPqnHDygso 2wj2Frh7FqzXGIUwwKYwAncQcqgP8x2/yBMmkknV1EVM2DVKoX6OcXikPgavQmGMja tXpg4JuqeTGA8x9bQqifQHy8YVF/W8VmlOkJPwJDXPn+HJqiplD6FM4J2OaeJab+0v gX41Wq5O7kI1IRkbnw7q9eK/DfKAT1i4jBb574ofOTIXhjQ930u1XjJK2y+AkcZGwz VQgsiSlJPrUOX7PFZc4gC35PHHaGtIX1W5ax6Q4y2Jxmo408JT8L+4iqeEQ75ioHBa RGOJXHqDbIeoQ== From: "Rafael J. Wysocki" To: Linux PM Cc: LKML , Daniel Lezcano , Lukasz Luba , Zhang Rui Subject: [PATCH for 6.13 v1 8/8] thermal: core: Add and use thermal zone guard Date: Tue, 10 Sep 2024 11:35:20 +0200 Message-ID: <3241904.5fSG56mABF@rjwysocki.net> In-Reply-To: <4920970.GXAFRqVoOG@rjwysocki.net> References: <4920970.GXAFRqVoOG@rjwysocki.net> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-CLIENT-IP: 195.136.19.94 X-CLIENT-HOSTNAME: 195.136.19.94 X-VADE-SPAMSTATE: spam:low X-VADE-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeftddrudeiledgudejucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecujffqoffgrffnpdggtffipffknecuuegrihhlohhuthemucduhedtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenogfuphgrmhfkphculdeftddtmdenucfjughrpefhvfevufffkfgjfhgggfgtsehtufertddttdejnecuhfhrohhmpedftfgrfhgrvghlucflrdcuhgihshhotghkihdfuceorhhjfiesrhhjfiihshhotghkihdrnhgvtheqnecuggftrfgrthhtvghrnhepvdffueeitdfgvddtudegueejtdffteetgeefkeffvdeftddttdeuhfegfedvjefhnecukfhppeduleehrddufeeirdduledrleegnecuufhprghmkfhppeduleehrddufeeirdduledrleegnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehinhgvthepudelhedrudefiedrudelrdelgedphhgvlhhopehkrhgvrggthhgvrhdrlhhotggrlhhnvghtpdhmrghilhhfrhhomheprhhjfiesrhhjfiihshhotghkihdrnhgvthdpnhgspghrtghpthhtohephedprhgtphhtthhopehlihhnuhigqdhpmhesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopehlihhnuhigqdhkvghrnhgvlhesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopegurghnihgvlhdrlhgviigtrghnoheslhhinhgrrhhordhorhhgpdhrtghpthhtoheplhhukhgrshiirdhluhgsrgesrghrmhdrtghomhdprhgtphhtthhopehruhhirdiihhgrnhhgsehinhhtvghlrdgtohhm X-DCC--Metrics: v370.home.net.pl 1024; Body=5 Fuz1=5 Fuz2=5 From: Rafael J. Wysocki Add and use a special guard for thermal zones. This allows quite a few error code paths to be simplified among other things and brings in a noticeable code size reduction for a good measure. No intentional functional impact. Signed-off-by: Rafael J. Wysocki --- drivers/thermal/thermal_core.c | 67 +++++++++++++------------------ drivers/thermal/thermal_core.h | 4 + drivers/thermal/thermal_helpers.c | 17 ++----- drivers/thermal/thermal_sysfs.c | 81 ++++++++++++++++---------------------- drivers/thermal/thermal_trip.c | 8 --- 5 files changed, 76 insertions(+), 101 deletions(-) Index: linux-pm/drivers/thermal/thermal_core.h =================================================================== --- linux-pm.orig/drivers/thermal/thermal_core.h +++ linux-pm/drivers/thermal/thermal_core.h @@ -9,6 +9,7 @@ #ifndef __THERMAL_CORE_H__ #define __THERMAL_CORE_H__ +#include #include #include @@ -146,6 +147,9 @@ struct thermal_zone_device { struct thermal_trip_desc trips[] __counted_by(num_trips); }; +DEFINE_GUARD(thermal_zone, struct thermal_zone_device *, mutex_lock(&_T->lock), + mutex_unlock(&_T->lock)) + /* Initial thermal zone temperature. */ #define THERMAL_TEMP_INIT INT_MIN Index: linux-pm/drivers/thermal/thermal_sysfs.c =================================================================== --- linux-pm.orig/drivers/thermal/thermal_sysfs.c +++ linux-pm/drivers/thermal/thermal_sysfs.c @@ -50,13 +50,13 @@ static ssize_t mode_show(struct device *dev, struct device_attribute *attr, char *buf) { struct thermal_zone_device *tz = to_thermal_zone(dev); - int enabled; - mutex_lock(&tz->lock); - enabled = tz->mode == THERMAL_DEVICE_ENABLED; - mutex_unlock(&tz->lock); + guard(thermal_zone)(tz); - return sprintf(buf, "%s\n", enabled ? "enabled" : "disabled"); + if (tz->mode == THERMAL_DEVICE_ENABLED) + return sprintf(buf, "enabled\n"); + + return sprintf(buf, "disabled\n"); } static ssize_t @@ -103,38 +103,34 @@ trip_point_temp_store(struct device *dev { struct thermal_trip *trip = thermal_trip_of_attr(attr, temp); struct thermal_zone_device *tz = to_thermal_zone(dev); - int ret, temp; + int temp; - ret = kstrtoint(buf, 10, &temp); - if (ret) + if (kstrtoint(buf, 10, &temp)) return -EINVAL; - mutex_lock(&tz->lock); + guard(thermal_zone)(tz); if (temp == trip->temperature) - goto unlock; + return count; /* Arrange the condition to avoid integer overflows. */ if (temp != THERMAL_TEMP_INVALID && - temp <= trip->hysteresis + THERMAL_TEMP_INVALID) { - ret = -EINVAL; - goto unlock; - } + temp <= trip->hysteresis + THERMAL_TEMP_INVALID) + return -EINVAL; if (tz->ops.set_trip_temp) { + int ret; + ret = tz->ops.set_trip_temp(tz, trip, temp); if (ret) - goto unlock; + return ret; } thermal_zone_set_trip_temp(tz, trip, temp); __thermal_zone_device_update(tz, THERMAL_TRIP_CHANGED); -unlock: - mutex_unlock(&tz->lock); - - return ret ? ret : count; + return count; } static ssize_t @@ -152,16 +148,15 @@ trip_point_hyst_store(struct device *dev { struct thermal_trip *trip = thermal_trip_of_attr(attr, hyst); struct thermal_zone_device *tz = to_thermal_zone(dev); - int ret, hyst; + int hyst; - ret = kstrtoint(buf, 10, &hyst); - if (ret || hyst < 0) + if (kstrtoint(buf, 10, &hyst) || hyst < 0) return -EINVAL; - mutex_lock(&tz->lock); + guard(thermal_zone)(tz); if (hyst == trip->hysteresis) - goto unlock; + return count; /* * Allow the hysteresis to be updated when the temperature is invalid @@ -171,22 +166,17 @@ trip_point_hyst_store(struct device *dev */ if (trip->temperature == THERMAL_TEMP_INVALID) { WRITE_ONCE(trip->hysteresis, hyst); - goto unlock; + return count; } - if (trip->temperature - hyst <= THERMAL_TEMP_INVALID) { - ret = -EINVAL; - goto unlock; - } + if (trip->temperature - hyst <= THERMAL_TEMP_INVALID) + return -EINVAL; thermal_zone_set_trip_hyst(tz, trip, hyst); __thermal_zone_device_update(tz, THERMAL_TRIP_CHANGED); -unlock: - mutex_unlock(&tz->lock); - - return ret ? ret : count; + return count; } static ssize_t @@ -236,25 +226,26 @@ emul_temp_store(struct device *dev, stru const char *buf, size_t count) { struct thermal_zone_device *tz = to_thermal_zone(dev); - int ret = 0; int temperature; if (kstrtoint(buf, 10, &temperature)) return -EINVAL; - mutex_lock(&tz->lock); + guard(thermal_zone)(tz); - if (!tz->ops.set_emul_temp) - tz->emul_temperature = temperature; - else - ret = tz->ops.set_emul_temp(tz, temperature); + if (tz->ops.set_emul_temp) { + int ret; - if (!ret) - __thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED); + ret = tz->ops.set_emul_temp(tz, temperature); + if (ret) + return ret; + } else { + tz->emul_temperature = temperature; + } - mutex_unlock(&tz->lock); + __thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED); - return ret ? ret : count; + return count; } static DEVICE_ATTR_WO(emul_temp); #endif @@ -894,13 +885,11 @@ ssize_t weight_store(struct device *dev, instance = container_of(attr, struct thermal_instance, weight_attr); /* Don't race with governors using the 'weight' value */ - mutex_lock(&tz->lock); + guard(thermal_zone)(tz); instance->weight = weight; thermal_governor_update_tz(tz, THERMAL_INSTANCE_WEIGHT_CHANGED); - mutex_unlock(&tz->lock); - return count; } Index: linux-pm/drivers/thermal/thermal_trip.c =================================================================== --- linux-pm.orig/drivers/thermal/thermal_trip.c +++ linux-pm/drivers/thermal/thermal_trip.c @@ -45,13 +45,9 @@ int thermal_zone_for_each_trip(struct th int (*cb)(struct thermal_trip *, void *), void *data) { - int ret; + guard(thermal_zone)(tz); - mutex_lock(&tz->lock); - ret = for_each_thermal_trip(tz, cb, data); - mutex_unlock(&tz->lock); - - return ret; + return for_each_thermal_trip(tz, cb, data); } EXPORT_SYMBOL_GPL(thermal_zone_for_each_trip); Index: linux-pm/drivers/thermal/thermal_helpers.c =================================================================== --- linux-pm.orig/drivers/thermal/thermal_helpers.c +++ linux-pm/drivers/thermal/thermal_helpers.c @@ -60,13 +60,13 @@ bool thermal_trip_is_bound_to_cdev(struc { bool ret; - mutex_lock(&tz->lock); + guard(thermal_zone)(tz); + mutex_lock(&cdev->lock); ret = thermal_instance_present(tz, cdev, trip); mutex_unlock(&cdev->lock); - mutex_unlock(&tz->lock); return ret; } @@ -138,19 +138,14 @@ int thermal_zone_get_temp(struct thermal if (IS_ERR_OR_NULL(tz)) return -EINVAL; - mutex_lock(&tz->lock); + guard(thermal_zone)(tz); - if (!tz->ops.get_temp) { - ret = -EINVAL; - goto unlock; - } + if (!tz->ops.get_temp) + return -EINVAL; ret = __thermal_zone_get_temp(tz, temp); if (!ret && *temp <= THERMAL_TEMP_INVALID) - ret = -ENODATA; - -unlock: - mutex_unlock(&tz->lock); + return -ENODATA; return ret; } Index: linux-pm/drivers/thermal/thermal_core.c =================================================================== --- linux-pm.orig/drivers/thermal/thermal_core.c +++ linux-pm/drivers/thermal/thermal_core.c @@ -199,16 +199,13 @@ int thermal_zone_device_set_policy(struc int ret = -EINVAL; mutex_lock(&thermal_governor_lock); - mutex_lock(&tz->lock); - gov = __find_governor(strim(policy)); - if (!gov) - goto exit; + guard(thermal_zone)(tz); - ret = thermal_set_governor(tz, gov); + gov = __find_governor(strim(policy)); + if (gov) + ret = thermal_set_governor(tz, gov); -exit: - mutex_unlock(&tz->lock); mutex_unlock(&thermal_governor_lock); thermal_notify_tz_gov_change(tz, policy); @@ -608,26 +605,18 @@ static int thermal_zone_device_set_mode( { int ret; - mutex_lock(&tz->lock); + guard(thermal_zone)(tz); /* do nothing if mode isn't changing */ - if (mode == tz->mode) { - mutex_unlock(&tz->lock); - + if (mode == tz->mode) return 0; - } ret = __thermal_zone_device_set_mode(tz, mode); - if (ret) { - mutex_unlock(&tz->lock); - + if (ret) return ret; - } __thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED); - mutex_unlock(&tz->lock); - if (mode == THERMAL_DEVICE_ENABLED) thermal_notify_tz_enable(tz); else @@ -656,10 +645,10 @@ static bool thermal_zone_is_present(stru void thermal_zone_device_update(struct thermal_zone_device *tz, enum thermal_notify_event event) { - mutex_lock(&tz->lock); + guard(thermal_zone)(tz); + if (thermal_zone_is_present(tz)) __thermal_zone_device_update(tz, event); - mutex_unlock(&tz->lock); } EXPORT_SYMBOL_GPL(thermal_zone_device_update); @@ -936,7 +925,7 @@ static void thermal_zone_cdev_bind(struc if (!tz->ops.should_bind) return; - mutex_lock(&tz->lock); + guard(thermal_zone)(tz); for_each_trip_desc(tz, td) { struct cooling_spec c = { @@ -953,8 +942,6 @@ static void thermal_zone_cdev_bind(struc if (ret) print_bind_err_msg(tz, td, cdev, ret); } - - mutex_unlock(&tz->lock); } /** @@ -1259,12 +1246,10 @@ static void thermal_zone_cdev_unbind(str { struct thermal_trip_desc *td; - mutex_lock(&tz->lock); + guard(thermal_zone)(tz); for_each_trip_desc(tz, td) thermal_unbind_cdev_from_trip(tz, td, cdev); - - mutex_unlock(&tz->lock); } /** @@ -1310,7 +1295,7 @@ int thermal_zone_get_crit_temp(struct th if (tz->ops.get_crit_temp) return tz->ops.get_crit_temp(tz, temp); - mutex_lock(&tz->lock); + guard(thermal_zone)(tz); for_each_trip_desc(tz, td) { const struct thermal_trip *trip = &td->trip; @@ -1322,12 +1307,17 @@ int thermal_zone_get_crit_temp(struct th } } - mutex_unlock(&tz->lock); - return ret; } EXPORT_SYMBOL_GPL(thermal_zone_get_crit_temp); +static void thermal_zone_add_to_list(struct thermal_zone_device *tz) +{ + guard(thermal_zone)(tz); + + list_add_tail(&tz->node, &thermal_tz_list); +} + /** * thermal_zone_device_register_with_trips() - register a new thermal zone device * @type: the thermal zone device type @@ -1488,9 +1478,7 @@ thermal_zone_device_register_with_trips( mutex_lock(&thermal_list_lock); - mutex_lock(&tz->lock); - list_add_tail(&tz->node, &thermal_tz_list); - mutex_unlock(&tz->lock); + thermal_zone_add_to_list(tz); /* Bind cooling devices for this zone */ list_for_each_entry(cdev, &thermal_cdev_list, node) @@ -1557,6 +1545,13 @@ struct device *thermal_zone_device(struc } EXPORT_SYMBOL_GPL(thermal_zone_device); +static void thermal_zone_del_from_list(struct thermal_zone_device *tz) +{ + guard(thermal_zone)(tz); + + list_del(&tz->node); +} + /** * thermal_zone_device_unregister - removes the registered thermal zone device * @tz: the thermal zone device to remove @@ -1581,9 +1576,7 @@ void thermal_zone_device_unregister(stru return; } - mutex_lock(&tz->lock); - list_del(&tz->node); - mutex_unlock(&tz->lock); + thermal_zone_del_from_list(tz); /* Unbind all cdevs associated with 'this' thermal zone */ list_for_each_entry(cdev, &thermal_cdev_list, node) @@ -1656,7 +1649,7 @@ static void thermal_zone_device_resume(s tz = container_of(work, struct thermal_zone_device, poll_queue.work); - mutex_lock(&tz->lock); + guard(thermal_zone)(tz); tz->suspended = false; @@ -1667,8 +1660,6 @@ static void thermal_zone_device_resume(s complete(&tz->resume); tz->resuming = false; - - mutex_unlock(&tz->lock); } static int thermal_pm_notify(struct notifier_block *nb,