From patchwork Fri Oct 15 17:01:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Rafael J. Wysocki" X-Patchwork-Id: 12562569 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DE1CCC43219 for ; Fri, 15 Oct 2021 17:04:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C41D960F25 for ; Fri, 15 Oct 2021 17:04:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241970AbhJORHA (ORCPT ); Fri, 15 Oct 2021 13:07:00 -0400 Received: from cloudserver094114.home.pl ([79.96.170.134]:54332 "EHLO cloudserver094114.home.pl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241952AbhJORG5 (ORCPT ); Fri, 15 Oct 2021 13:06:57 -0400 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 3.0.0) id b0d89b5bf84f41b0; Fri, 15 Oct 2021 19:04:49 +0200 Received: from kreacher.localnet (unknown [213.134.175.255]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by v370.home.net.pl (Postfix) with ESMTPSA id CA68A66A8C0; Fri, 15 Oct 2021 19:04:48 +0200 (CEST) From: "Rafael J. Wysocki" To: Linux ACPI Cc: Linux PM , LKML , Mika Westerberg , Linux PCI Subject: [PATCH v1 1/3] ACPI: PM: Turn off unused wakeup power resources Date: Fri, 15 Oct 2021 19:01:28 +0200 Message-ID: <4657519.GXAFRqVoOG@kreacher> In-Reply-To: <4347933.LvFx2qVVIh@kreacher> References: <4347933.LvFx2qVVIh@kreacher> MIME-Version: 1.0 X-CLIENT-IP: 213.134.175.255 X-CLIENT-HOSTNAME: 213.134.175.255 X-VADE-SPAMSTATE: clean X-VADE-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedvtddrvddugedguddtjecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfjqffogffrnfdpggftiffpkfenuceurghilhhouhhtmecuudehtdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurhephffvufffkfgjfhgggfgtsehtufertddttdejnecuhfhrohhmpedftfgrfhgrvghlucflrdcuhgihshhotghkihdfuceorhhjfiesrhhjfiihshhotghkihdrnhgvtheqnecuggftrfgrthhtvghrnhepvdejlefghfeiudektdelkeekvddugfeghffggeejgfeukeejleevgffgvdeluddtnecukfhppedvudefrddufeegrddujeehrddvheehnecuvehluhhsthgvrhfuihiivgepudenucfrrghrrghmpehinhgvthepvddufedrudefgedrudejhedrvdehhedphhgvlhhopehkrhgvrggthhgvrhdrlhhotggrlhhnvghtpdhmrghilhhfrhhomhepfdftrghfrggvlhculfdrucghhihsohgtkhhifdcuoehrjhifsehrjhifhihsohgtkhhirdhnvghtqedprhgtphhtthhopehlihhnuhigqdgrtghpihesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopehlihhnuhigqdhpmhesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopehlihhnuhigqdhkvghrnhgvlhesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopehmihhkrgdrfigvshhtvghrsggvrhhgsehlihhnuhigrdhinhhtvghlrdgtohhmpdhrtghpthht oheplhhinhhugidqphgtihesvhhgvghrrdhkvghrnhgvlhdrohhrgh X-DCC--Metrics: v370.home.net.pl 1024; Body=5 Fuz1=5 Fuz2=5 Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org From: Rafael J. Wysocki If an ACPI power resource is found to be "on" during the initialization of the list of wakeup power resources of a device, it is reference counted and its wakeup_enabled flag is set, which is problematic if the deivce in question is the only user of the given power resource, it is never runtime-suspended and it is not allowed to wake up the system from sleep, because in that case the given power resource will stay "on" until the system reboots and energy will be wasted. It is better to simply turn off wakeup power resources that are "on" during the initialization unless their reference counters are not zero, because that may be the only opportunity to prevent them from staying in the "on" state all the time. Fixes: b5d667eb392e ("ACPI / PM: Take unusual configurations of power resources into account") Signed-off-by: Rafael J. Wysocki --- drivers/acpi/power.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) Index: linux-pm/drivers/acpi/power.c =================================================================== --- linux-pm.orig/drivers/acpi/power.c +++ linux-pm/drivers/acpi/power.c @@ -615,20 +615,19 @@ int acpi_power_wakeup_list_init(struct l list_for_each_entry(entry, list, node) { struct acpi_power_resource *resource = entry->resource; - int result; u8 state; mutex_lock(&resource->resource_lock); - result = acpi_power_get_state(resource, &state); - if (result) { - mutex_unlock(&resource->resource_lock); - return result; - } - if (state == ACPI_POWER_RESOURCE_STATE_ON) { - resource->ref_count++; - resource->wakeup_enabled = true; - } + /* + * Make sure that the power resource state and its reference + * counter value are consistent with each other. + */ + if (!resource->ref_count && + !acpi_power_get_state(resource, &state) && + state == ACPI_POWER_RESOURCE_STATE_ON) + __acpi_power_off(resource); + if (system_level > resource->system_level) system_level = resource->system_level; From patchwork Fri Oct 15 17:03:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Rafael J. Wysocki" X-Patchwork-Id: 12562567 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 89F08C43219 for ; Fri, 15 Oct 2021 17:04:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6E36A611CE for ; Fri, 15 Oct 2021 17:04:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241950AbhJORG4 (ORCPT ); Fri, 15 Oct 2021 13:06:56 -0400 Received: from cloudserver094114.home.pl ([79.96.170.134]:64962 "EHLO cloudserver094114.home.pl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241934AbhJORGz (ORCPT ); Fri, 15 Oct 2021 13:06:55 -0400 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 3.0.0) id 168a8063eefe7ff3; Fri, 15 Oct 2021 19:04:48 +0200 Received: from kreacher.localnet (unknown [213.134.175.255]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by v370.home.net.pl (Postfix) with ESMTPSA id 4440566A8C0; Fri, 15 Oct 2021 19:04:47 +0200 (CEST) From: "Rafael J. Wysocki" To: Linux ACPI Cc: Linux PM , LKML , Mika Westerberg , Linux PCI Subject: [PATCH v1 2/3] ACPI: PM: Fix sharing of wakeup power resources Date: Fri, 15 Oct 2021 19:03:16 +0200 Message-ID: <2077987.irdbgypaU6@kreacher> In-Reply-To: <4347933.LvFx2qVVIh@kreacher> References: <4347933.LvFx2qVVIh@kreacher> MIME-Version: 1.0 X-CLIENT-IP: 213.134.175.255 X-CLIENT-HOSTNAME: 213.134.175.255 X-VADE-SPAMSTATE: clean X-VADE-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedvtddrvddugedguddtjecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfjqffogffrnfdpggftiffpkfenuceurghilhhouhhtmecuudehtdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurhephffvufffkfgjfhgggfgtsehtufertddttdejnecuhfhrohhmpedftfgrfhgrvghlucflrdcuhgihshhotghkihdfuceorhhjfiesrhhjfiihshhotghkihdrnhgvtheqnecuggftrfgrthhtvghrnhepvdejlefghfeiudektdelkeekvddugfeghffggeejgfeukeejleevgffgvdeluddtnecukfhppedvudefrddufeegrddujeehrddvheehnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehinhgvthepvddufedrudefgedrudejhedrvdehhedphhgvlhhopehkrhgvrggthhgvrhdrlhhotggrlhhnvghtpdhmrghilhhfrhhomhepfdftrghfrggvlhculfdrucghhihsohgtkhhifdcuoehrjhifsehrjhifhihsohgtkhhirdhnvghtqedprhgtphhtthhopehlihhnuhigqdgrtghpihesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopehlihhnuhigqdhpmhesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopehlihhnuhigqdhkvghrnhgvlhesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopehmihhkrgdrfigvshhtvghrsggvrhhgsehlihhnuhigrdhinhhtvghlrdgtohhmpdhrtghpthht oheplhhinhhugidqphgtihesvhhgvghrrdhkvghrnhgvlhdrohhrgh X-DCC--Metrics: v370.home.net.pl 1024; Body=5 Fuz1=5 Fuz2=5 Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org From: Rafael J. Wysocki If an ACPI wakeup power resource is shared between multiple devices, it may not be managed correctly. Suppose, for example, that two devices, A and B, share a wakeup power resource P whose wakeup_enabled flag is 0 initially. Next, suppose that wakeup power is enabled for A and B, in this order, and disabled for B. When wakeup power is enabled for A, P will be turned on and its wakeup_enabled flag will be set. Next, when wakeup power is enabled for B, P will not be touched, because its wakeup_enabled flag is set. Now, when wakeup power is disabled for B, P will be turned off which is incorrect, because A will still need P in order to signal wakeup. Moreover, if wakeup power is enabled for A and then disabled for B, the latter will cause P to be turned off incorrectly (it will be still needed by A), because acpi_disable_wakeup_device_power() is allowed to manipulate power resources when the wakeup.prepare_count counter of the given device is 0. While the first issue could be addressed by changing the wakeup_enabled power resource flag into a counter, addressing the second one requires modifying acpi_disable_wakeup_device_power() to do nothing when the target device's wakeup.prepare_count reference counter is zero and that would cause the new counter to be redundant. Namely, if acpi_disable_wakeup_device_power() is modified as per the above, every change of the new counter following a wakeup.prepare_count change would be reflected by the analogous change of the main reference counter of the given power resource. Accordingly, modify acpi_disable_wakeup_device_power() to do nothing when the target device's wakeup.prepare_count reference counter is zero and drop the power resource wakeup_enabled flag altogether. While at it, ensure that all of the power resources that can be turned off will be turned off when disabling device wakeup due to a power resource manipulation error, to prevent energy from being wasted. Fixes: b5d667eb392e ("ACPI / PM: Take unusual configurations of power resources into account") Signed-off-by: Rafael J. Wysocki Reported-by: kernel test robot Reported-by: kernel test robot --- drivers/acpi/power.c | 73 ++++++++++++++++++--------------------------------- 1 file changed, 26 insertions(+), 47 deletions(-) Index: linux-pm/drivers/acpi/power.c =================================================================== --- linux-pm.orig/drivers/acpi/power.c +++ linux-pm/drivers/acpi/power.c @@ -52,7 +52,6 @@ struct acpi_power_resource { u32 order; unsigned int ref_count; u8 state; - bool wakeup_enabled; struct mutex resource_lock; struct list_head dependents; }; @@ -710,8 +709,7 @@ int acpi_device_sleep_wake(struct acpi_d */ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state) { - struct acpi_power_resource_entry *entry; - int err = 0; + int err; if (!dev || !dev->wakeup.flags.valid) return -EINVAL; @@ -721,26 +719,13 @@ int acpi_enable_wakeup_device_power(stru if (dev->wakeup.prepare_count++) goto out; - list_for_each_entry(entry, &dev->wakeup.resources, node) { - struct acpi_power_resource *resource = entry->resource; - - mutex_lock(&resource->resource_lock); - - if (!resource->wakeup_enabled) { - err = acpi_power_on_unlocked(resource); - if (!err) - resource->wakeup_enabled = true; - } - - mutex_unlock(&resource->resource_lock); - - if (err) { - dev_err(&dev->dev, - "Cannot turn wakeup power resources on\n"); - dev->wakeup.flags.valid = 0; - goto out; - } + err = acpi_power_on_list(&dev->wakeup.resources); + if (err) { + dev_err(&dev->dev, "Cannot turn on wakeup power resources\n"); + dev->wakeup.flags.valid = 0; + goto out; } + /* * Passing 3 as the third argument below means the device may be * put into arbitrary power state afterward. @@ -763,46 +748,40 @@ int acpi_enable_wakeup_device_power(stru int acpi_disable_wakeup_device_power(struct acpi_device *dev) { struct acpi_power_resource_entry *entry; - int err = 0; + int err; if (!dev || !dev->wakeup.flags.valid) return -EINVAL; mutex_lock(&acpi_device_lock); - if (--dev->wakeup.prepare_count > 0) + if (dev->wakeup.prepare_count > 1) { + dev->wakeup.prepare_count--; goto out; + } - /* - * Executing the code below even if prepare_count is already zero when - * the function is called may be useful, for example for initialisation. - */ - if (dev->wakeup.prepare_count < 0) - dev->wakeup.prepare_count = 0; + /* Do nothing if wakeup power has not been enabled for this device. */ + if (!dev->wakeup.prepare_count) + goto out; err = acpi_device_sleep_wake(dev, 0, 0, 0); if (err) goto out; + /* + * All of the power resources in the list need to be turned off even if + * there are errors. + */ list_for_each_entry(entry, &dev->wakeup.resources, node) { - struct acpi_power_resource *resource = entry->resource; - - mutex_lock(&resource->resource_lock); - - if (resource->wakeup_enabled) { - err = acpi_power_off_unlocked(resource); - if (!err) - resource->wakeup_enabled = false; - } - - mutex_unlock(&resource->resource_lock); + int ret; - if (err) { - dev_err(&dev->dev, - "Cannot turn wakeup power resources off\n"); - dev->wakeup.flags.valid = 0; - break; - } + ret = acpi_power_off(entry->resource); + if (ret && !err) + err = ret; + } + if (err) { + dev_err(&dev->dev, "Cannot turn off wakeup power resources\n"); + dev->wakeup.flags.valid = 0; } out: From patchwork Fri Oct 15 17:04:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Rafael J. Wysocki" X-Patchwork-Id: 12562565 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9D825C433EF for ; Fri, 15 Oct 2021 17:04:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7BC68611C8 for ; Fri, 15 Oct 2021 17:04:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237811AbhJORGz (ORCPT ); Fri, 15 Oct 2021 13:06:55 -0400 Received: from cloudserver094114.home.pl ([79.96.170.134]:47804 "EHLO cloudserver094114.home.pl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237791AbhJORGy (ORCPT ); Fri, 15 Oct 2021 13:06:54 -0400 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 3.0.0) id 6e753915d7a8dc33; Fri, 15 Oct 2021 19:04:46 +0200 Received: from kreacher.localnet (unknown [213.134.175.255]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by v370.home.net.pl (Postfix) with ESMTPSA id 5A26C66A8C0; Fri, 15 Oct 2021 19:04:45 +0200 (CEST) From: "Rafael J. Wysocki" To: Linux ACPI Cc: Linux PM , LKML , Mika Westerberg , Linux PCI Subject: [PATCH v1 3/3] ACPI: PM: Turn off wakeup power resources on _DSW/_PSW errors Date: Fri, 15 Oct 2021 19:04:26 +0200 Message-ID: <2795050.e9J7NaK4W3@kreacher> In-Reply-To: <4347933.LvFx2qVVIh@kreacher> References: <4347933.LvFx2qVVIh@kreacher> MIME-Version: 1.0 X-CLIENT-IP: 213.134.175.255 X-CLIENT-HOSTNAME: 213.134.175.255 X-VADE-SPAMSTATE: clean X-VADE-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedvtddrvddugedguddtjecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfjqffogffrnfdpggftiffpkfenuceurghilhhouhhtmecuudehtdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurhephffvufffkfgjfhgggfgtsehtufertddttdejnecuhfhrohhmpedftfgrfhgrvghlucflrdcuhgihshhotghkihdfuceorhhjfiesrhhjfiihshhotghkihdrnhgvtheqnecuggftrfgrthhtvghrnhepvdejlefghfeiudektdelkeekvddugfeghffggeejgfeukeejleevgffgvdeluddtnecukfhppedvudefrddufeegrddujeehrddvheehnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehinhgvthepvddufedrudefgedrudejhedrvdehhedphhgvlhhopehkrhgvrggthhgvrhdrlhhotggrlhhnvghtpdhmrghilhhfrhhomhepfdftrghfrggvlhculfdrucghhihsohgtkhhifdcuoehrjhifsehrjhifhihsohgtkhhirdhnvghtqedprhgtphhtthhopehlihhnuhigqdgrtghpihesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopehlihhnuhigqdhpmhesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopehlihhnuhigqdhkvghrnhgvlhesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopehmihhkrgdrfigvshhtvghrsggvrhhgsehlihhnuhigrdhinhhtvghlrdgtohhmpdhrtghpthht oheplhhinhhugidqphgtihesvhhgvghrrdhkvghrnhgvlhdrohhrgh X-DCC--Metrics: v370.home.net.pl 1024; Body=5 Fuz1=5 Fuz2=5 Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org From: Rafael J. Wysocki If acpi_device_sleep_wake() called by acpi_enable_wakeup_device_power() returns an error which means that the evaluation of either _DWS or _PSW has failed, turn off all of the device's wakeup power resources to be consistent with the clearing of dev->wakeup.prepare_count. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/power.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) Index: linux-pm/drivers/acpi/power.c =================================================================== --- linux-pm.orig/drivers/acpi/power.c +++ linux-pm/drivers/acpi/power.c @@ -731,8 +731,10 @@ int acpi_enable_wakeup_device_power(stru * put into arbitrary power state afterward. */ err = acpi_device_sleep_wake(dev, 1, sleep_state, 3); - if (err) + if (err) { + acpi_power_off_list(&dev->wakeup.resources); dev->wakeup.prepare_count = 0; + } out: mutex_unlock(&acpi_device_lock);