From patchwork Tue Feb 25 16:38:58 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Rafael J. Wysocki" X-Patchwork-Id: 868386 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 B064619ABD8; Tue, 25 Feb 2025 16:46:26 +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=1740501989; cv=none; b=tO+gamNLjXOHzWGZjsbptI40DCIrKkeYIzpgsEhHI45TthItBTGkZqQ/5O3+ntc+a0brDFYQImBedXxqcJzv+XFmnEMZ3p6nDx4yVJzvyf9nk5ek8b0ZdWbwFV26DteGV5yZH8VKF3PW+182ocDFbh/6gNoeKIeUBfSgbim01FE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740501989; c=relaxed/simple; bh=x5965uTvLwEkxn6TGr0SnrfvJHVrwkwk9tx8/ZMADy8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=nNCv7bHqZKNN/9XqrjqYrpmoskEr2wZWWNx918zih0qei4fiyHud56aMCpyE8fgeDSEEgiZuUG631F33Pa6bE0N1w4YGIK6t0Qss9kmqKVLPYzEvBNf8vZQk1/wP2l8ERq478JaE5bO8uSJGSCTT5vbjspOEWKKSvo8TWkBx3Ms= 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=XfYg5Twy; 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="XfYg5Twy" 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.1) id 8710ec574f47ab3a; Tue, 25 Feb 2025 17:46:19 +0100 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 A945322C28BF; Tue, 25 Feb 2025 17:46:18 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=rjwysocki.net; s=dkim; t=1740501979; bh=x5965uTvLwEkxn6TGr0SnrfvJHVrwkwk9tx8/ZMADy8=; h=From:Subject:Date; b=XfYg5Twy8jTZ1dk/m0qcpD4B9/jPzUcDZt4bm8WwVPhXlBcas4n7pW/RP2i6lnv6s J86yBP4npYsFbUScElvJzuq+Y0p/Sk7dvrFiQHcfO4cw3zi8pRLbpGR7gPswm/wYoH TYT/qbLRO+6zXnqy1pKceCQHceQx6YpecnsuMR384o5mASUteF5cvle5fHkKYSB0Oo 1rOq9DKOiVilkQC9b/KLg47TV2ylBuer6G61N/1jaf5cdsXmU/4E1Xl+QVghW70lh7 DMqK/acUNMdchtvMJbuP+o5Onj+tcBK32/tHHlD6uPfPA+n2VVbwwKPeQjBQMCWzlt naXMIEy4OAbDg== From: "Rafael J. Wysocki" To: Linux PM Cc: LKML , Alan Stern , Ulf Hansson , Johan Hovold , Manivannan Sadhasivam , Saravana Kannan Subject: [PATCH v1 1/5] PM: sleep: Rename power.async_in_progress to power.work_in_progress Date: Tue, 25 Feb 2025 17:38:58 +0100 Message-ID: <3338693.aeNJFYEL58@rjwysocki.net> In-Reply-To: <13709135.uLZWGnKmhe@rjwysocki.net> References: <13709135.uLZWGnKmhe@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: clean X-VADE-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgdekvddvvdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfjqffogffrnfdpggftiffpkfenuceurghilhhouhhtmecuudehtdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurhephffvvefufffkjghfggfgtgesthfuredttddtjeenucfhrhhomhepfdftrghfrggvlhculfdrucghhihsohgtkhhifdcuoehrjhifsehrjhifhihsohgtkhhirdhnvghtqeenucggtffrrghtthgvrhhnpedvffeuiedtgfdvtddugeeujedtffetteegfeekffdvfedttddtuefhgeefvdejhfenucfkphepudelhedrudefiedrudelrdelgeenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepihhnvghtpeduleehrddufeeirdduledrleegpdhhvghlohepkhhrvggrtghhvghrrdhlohgtrghlnhgvthdpmhgrihhlfhhrohhmpehrjhifsehrjhifhihsohgtkhhirdhnvghtpdhnsggprhgtphhtthhopeejpdhrtghpthhtoheplhhinhhugidqphhmsehvghgvrhdrkhgvrhhnvghlrdhorhhgpdhrtghpthhtoheplhhinhhugidqkhgvrhhnvghlsehvghgvrhdrkhgvrhhnvghlrdhorhhgpdhrtghpthhtohepshhtvghrnhesrhhofihlrghnugdrhhgrrhhvrghrugdrvgguuhdprhgtphhtthhopehulhhfrdhhrghnshhsohhnsehlihhnrghrohdrohhrghdprhgtphhtthhopehjohhhrghnsehkvghrnhgvlhdrohhrghdprhgtphh X-DCC--Metrics: v370.home.net.pl 1024; Body=7 Fuz1=7 Fuz2=7 From: Rafael J. Wysocki Rename the async_in_progress field in struct dev_pm_info to work_in_progress as after subsequent changes it will mean work in general rather than just async work. No functional impact. Signed-off-by: Rafael J. Wysocki --- drivers/base/power/main.c | 12 ++++++------ include/linux/pm.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -602,7 +602,7 @@ reinit_completion(&dev->power.completion); if (is_async(dev)) { - dev->power.async_in_progress = true; + dev->power.work_in_progress = true; get_device(dev); @@ -614,9 +614,9 @@ /* * Because async_schedule_dev_nocall() above has returned false or it * has not been called at all, func() is not running and it is safe to - * update the async_in_progress flag without extra synchronization. + * update the work_in_progress flag without extra synchronization. */ - dev->power.async_in_progress = false; + dev->power.work_in_progress = false; return false; } @@ -736,7 +736,7 @@ dev = to_device(dpm_noirq_list.next); list_move_tail(&dev->power.entry, &dpm_late_early_list); - if (!dev->power.async_in_progress) { + if (!dev->power.work_in_progress) { get_device(dev); mutex_unlock(&dpm_list_mtx); @@ -876,7 +876,7 @@ dev = to_device(dpm_late_early_list.next); list_move_tail(&dev->power.entry, &dpm_suspended_list); - if (!dev->power.async_in_progress) { + if (!dev->power.work_in_progress) { get_device(dev); mutex_unlock(&dpm_list_mtx); @@ -1042,7 +1042,7 @@ dev = to_device(dpm_suspended_list.next); list_move_tail(&dev->power.entry, &dpm_prepared_list); - if (!dev->power.async_in_progress) { + if (!dev->power.work_in_progress) { get_device(dev); mutex_unlock(&dpm_list_mtx); --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -679,7 +679,7 @@ bool wakeup_path:1; bool syscore:1; bool no_pm_callbacks:1; /* Owned by the PM core */ - bool async_in_progress:1; /* Owned by the PM core */ + bool work_in_progress:1; /* Owned by the PM core */ bool smart_suspend:1; /* Owned by the PM core */ bool must_resume:1; /* Owned by the PM core */ bool may_skip_resume:1; /* Set by subsystems */ From patchwork Tue Feb 25 16:39:40 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Rafael J. Wysocki" X-Patchwork-Id: 868866 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 CB17719AA63; Tue, 25 Feb 2025 16:46: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=1740501987; cv=none; b=B5oy5/ECYYoStzc1lCbI1iR6xI0WnBFCHnwzEzlaV+dxSwikN7/E3sBrAYtGtlXGzmk0ZmOc+34L5dOTuXy/u+2pnMMkqSKcDj1HOuZJGaEeebhdWcgGJtIXNlKbv5TXN9WujJeKf7QY5YMhc7bI+hp8noIWFCNJLne3MfRa3g0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740501987; c=relaxed/simple; bh=TXX6+lyM02BQDjNAokzwdr/qxJ0m9P3ixaNYCT5hmQA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=QgV8spRgxqclbYIL4vY8PIQds3L2kh88f+fUfzwFenhFZL0yFcU+8gm8tBTd5eElWyq7d1f9GP0Ot/RZfgkMs+fgsZnXUuJhSlxmrijz51l6khsTJYKFcjrnNASKg85BzygpgtSl0S9FXm1Db9+nqoJFSJXdx1pcIBoPM7OWKIM= 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=tthz19Uu; 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="tthz19Uu" 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.1) id 364f8efee1ad67b9; Tue, 25 Feb 2025 17:46:18 +0100 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 BA2D722C28BF; Tue, 25 Feb 2025 17:46:17 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=rjwysocki.net; s=dkim; t=1740501978; bh=TXX6+lyM02BQDjNAokzwdr/qxJ0m9P3ixaNYCT5hmQA=; h=From:Subject:Date; b=tthz19Uu3ngB+djs8zWyZyTs8TTaqsMV753Tlmrb84pB17EjXvf0p2e8VafnaX1I7 bxEbE1QPN8H2X/W7AFzN+hAGQYSfqJT7ltdIsnkzbBD21jit+qfMWNZl1v/BX93Zjt 4j4GUsxADbRLLgDkTqmWI0kZAPZMEXcV0jbKvc22DumA//DXK77MXnXNDsWbXgWl/j CvRU/VJcicNHnq8rAy143eYQsCSptwibre8bjPsQ1SR57bIJnFQr8do8jdpj9gG6C0 Ea+w82HsHoum4ccm/Wv/S5ACD3ZoDolzY0Qp+ter/rAFythszANnhxwc862PQx+7vM pVY07i3tSdNqA== From: "Rafael J. Wysocki" To: Linux PM Cc: LKML , Alan Stern , Ulf Hansson , Johan Hovold , Manivannan Sadhasivam , Saravana Kannan Subject: [PATCH v1 2/5] PM: sleep: Rearrange dpm_async_fn() and async state clearing Date: Tue, 25 Feb 2025 17:39:40 +0100 Message-ID: <8494650.T7Z3S40VBb@rjwysocki.net> In-Reply-To: <13709135.uLZWGnKmhe@rjwysocki.net> References: <13709135.uLZWGnKmhe@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: clean X-VADE-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgdekvddvvdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfjqffogffrnfdpggftiffpkfenuceurghilhhouhhtmecuudehtdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurhephffvvefufffkjghfggfgtgesthfuredttddtjeenucfhrhhomhepfdftrghfrggvlhculfdrucghhihsohgtkhhifdcuoehrjhifsehrjhifhihsohgtkhhirdhnvghtqeenucggtffrrghtthgvrhhnpedvffeuiedtgfdvtddugeeujedtffetteegfeekffdvfedttddtuefhgeefvdejhfenucfkphepudelhedrudefiedrudelrdelgeenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepihhnvghtpeduleehrddufeeirdduledrleegpdhhvghlohepkhhrvggrtghhvghrrdhlohgtrghlnhgvthdpmhgrihhlfhhrohhmpehrjhifsehrjhifhihsohgtkhhirdhnvghtpdhnsggprhgtphhtthhopeejpdhrtghpthhtoheplhhinhhugidqphhmsehvghgvrhdrkhgvrhhnvghlrdhorhhgpdhrtghpthhtoheplhhinhhugidqkhgvrhhnvghlsehvghgvrhdrkhgvrhhnvghlrdhorhhgpdhrtghpthhtohepshhtvghrnhesrhhofihlrghnugdrhhgrrhhvrghrugdrvgguuhdprhgtphhtthhopehulhhfrdhhrghnshhsohhnsehlihhnrghrohdrohhrghdprhgtphhtthhopehjohhhrghnsehkvghrnhgvlhdrohhrghdprhgtphh X-DCC--Metrics: v370.home.net.pl 1024; Body=7 Fuz1=7 Fuz2=7 From: Rafael J. Wysocki In preparation for subsequent changes, move the power.completion reinitialization along with clearing power.work_in_progress into a separate function called dpm_clear_async_state() and rearrange dpm_async_fn() to get rid of unnecessary indentation. No intentional functional impact. Signed-off-by: Rafael J. Wysocki --- drivers/base/power/main.c | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -599,27 +599,34 @@ static bool dpm_async_fn(struct device *dev, async_func_t func) { - reinit_completion(&dev->power.completion); + if (!is_async(dev)) + return false; - if (is_async(dev)) { - dev->power.work_in_progress = true; + dev->power.work_in_progress = true; - get_device(dev); + get_device(dev); - if (async_schedule_dev_nocall(func, dev)) - return true; + if (async_schedule_dev_nocall(func, dev)) + return true; + + put_device(dev); - put_device(dev); - } /* - * Because async_schedule_dev_nocall() above has returned false or it - * has not been called at all, func() is not running and it is safe to - * update the work_in_progress flag without extra synchronization. + * async_schedule_dev_nocall() above has returned false, so func() is + * not running and it is safe to update power.work_in_progress without + * extra synchronization. */ dev->power.work_in_progress = false; + return false; } +static void dpm_clear_async_state(struct device *dev) +{ + reinit_completion(&dev->power.completion); + dev->power.work_in_progress = false; +} + /** * device_resume_noirq - Execute a "noirq resume" callback for given device. * @dev: Device to handle. @@ -729,8 +736,10 @@ * Trigger the resume of "async" devices upfront so they don't have to * wait for the "non-async" ones they don't depend on. */ - list_for_each_entry(dev, &dpm_noirq_list, power.entry) + list_for_each_entry(dev, &dpm_noirq_list, power.entry) { + dpm_clear_async_state(dev); dpm_async_fn(dev, async_resume_noirq); + } while (!list_empty(&dpm_noirq_list)) { dev = to_device(dpm_noirq_list.next); @@ -869,8 +878,10 @@ * Trigger the resume of "async" devices upfront so they don't have to * wait for the "non-async" ones they don't depend on. */ - list_for_each_entry(dev, &dpm_late_early_list, power.entry) + list_for_each_entry(dev, &dpm_late_early_list, power.entry) { + dpm_clear_async_state(dev); dpm_async_fn(dev, async_resume_early); + } while (!list_empty(&dpm_late_early_list)) { dev = to_device(dpm_late_early_list.next); @@ -1035,8 +1046,10 @@ * Trigger the resume of "async" devices upfront so they don't have to * wait for the "non-async" ones they don't depend on. */ - list_for_each_entry(dev, &dpm_suspended_list, power.entry) + list_for_each_entry(dev, &dpm_suspended_list, power.entry) { + dpm_clear_async_state(dev); dpm_async_fn(dev, async_resume); + } while (!list_empty(&dpm_suspended_list)) { dev = to_device(dpm_suspended_list.next); @@ -1314,6 +1327,7 @@ list_move(&dev->power.entry, &dpm_noirq_list); + dpm_clear_async_state(dev); if (dpm_async_fn(dev, async_suspend_noirq)) continue; @@ -1491,6 +1505,7 @@ list_move(&dev->power.entry, &dpm_late_early_list); + dpm_clear_async_state(dev); if (dpm_async_fn(dev, async_suspend_late)) continue; @@ -1758,6 +1773,7 @@ list_move(&dev->power.entry, &dpm_suspended_list); + dpm_clear_async_state(dev); if (dpm_async_fn(dev, async_suspend)) continue; From patchwork Tue Feb 25 16:45:22 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Rafael J. Wysocki" X-Patchwork-Id: 868387 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 C886019A288; Tue, 25 Feb 2025 16:46: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=1740501987; cv=none; b=bmaGZpz2FCpgA2USnSvwdojl6jZC+BrDHQ5uLVhgCMR8tgfm9JapwL+Kr2M3dWTHqWMM4+j77Y5SJ5NdL/WrjTVlwG0mdKKNOaNDBc3cBhRlULO6u2iNwDaBfptsNg+9Z1vREaf82xClj9m1FNAEAe8vUy70xeeFgogPIVXuEMo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740501987; c=relaxed/simple; bh=+k1w3zIKJCdHQc3g5rjCyOSmrNbD4FRJ5HlfhHPq9GA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=iTq7HGxwepK/05jzLrod9hDxwmKQ9vnzweeXr/Y802LOFCUNrxkZKY/U47dT6v4BFcwuyEXMt6wVFVLS3KoWBioXc00vn8MyuKl1cSh03FiLn7bAg9co+9kDY32GPcvJg6dypbRo7wUieV43oHQ3oatkBMqaK77KaHaF7Uh1agQ= 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=fLA0Ig5x; 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="fLA0Ig5x" 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.1) id 99d3f2a535374919; Tue, 25 Feb 2025 17:46:17 +0100 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 CAFB622C28BF; Tue, 25 Feb 2025 17:46:16 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=rjwysocki.net; s=dkim; t=1740501977; bh=+k1w3zIKJCdHQc3g5rjCyOSmrNbD4FRJ5HlfhHPq9GA=; h=From:Subject:Date; b=fLA0Ig5xjF91+fuwfuy0zRP0pL6tRJdi/dN0D4abz5IZpoBP+hrJGWdgU7zghNw43 xZ1KmXjCsfidROcmHu62SFS1YjrICVL1NPuhD7L8I+a4NUaO3CxhnOJX11Pf2A4Yk+ 0ZPUbt+WNIFG1N2Hla4i1y1THwR9jCSPKCKBIfB0uT4U0/xwnYLvMmvR3xWge/qEL9 5Wy/um4yjftSi2h5g37gEGxYgvkqFIGf4al9pZD7/XwUjlSE10VdQIRgdxuODT1YoU gehVZUux2xjHrXdDckCffMNAOvjNpcqcdaRyc5XEFryN6hDsrxjws7X7feX69WHX3J 8sVYiUYXYap1w== From: "Rafael J. Wysocki" To: Linux PM Cc: LKML , Alan Stern , Ulf Hansson , Johan Hovold , Manivannan Sadhasivam , Saravana Kannan Subject: [PATCH v1 3/5] PM: sleep: Resume children right after resuming the parent Date: Tue, 25 Feb 2025 17:45:22 +0100 Message-ID: <1819312.VLH7GnMWUR@rjwysocki.net> In-Reply-To: <13709135.uLZWGnKmhe@rjwysocki.net> References: <13709135.uLZWGnKmhe@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: clean X-VADE-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgdekvddvudcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfjqffogffrnfdpggftiffpkfenuceurghilhhouhhtmecuudehtdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurhephffvvefufffkjghfggfgtgesthfuredttddtjeenucfhrhhomhepfdftrghfrggvlhculfdrucghhihsohgtkhhifdcuoehrjhifsehrjhifhihsohgtkhhirdhnvghtqeenucggtffrrghtthgvrhhnpeefudduuedtuefgleffudeigeeitdeufeelvdejgefftdethffhhfethfeljefgteenucffohhmrghinhepkhgvrhhnvghlrdhorhhgnecukfhppeduleehrddufeeirdduledrleegnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehinhgvthepudelhedrudefiedrudelrdelgedphhgvlhhopehkrhgvrggthhgvrhdrlhhotggrlhhnvghtpdhmrghilhhfrhhomheprhhjfiesrhhjfiihshhotghkihdrnhgvthdpnhgspghrtghpthhtohepjedprhgtphhtthhopehlihhnuhigqdhpmhesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopehlihhnuhigqdhkvghrnhgvlhesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopehsthgvrhhnsehrohiflhgrnhgurdhhrghrvhgrrhgurdgvughupdhrtghpthhtohepuhhlfhdrhhgrnhhsshhonheslhhinhgrrhhordhorhhgpdhrtghpthhtohepjhh X-DCC--Metrics: v370.home.net.pl 1024; Body=7 Fuz1=7 Fuz2=7 From: Rafael J. Wysocki According to [1], the handling of device suspend and resume, and particularly the latter, involves unnecessary overhead related to starting new async work items for devices that cannot make progress right away because they have to wait for other devices. To reduce this problem in the resume path, use the observation that starting the async resume of the children of a device after resuming the parent is likely to produce less scheduling and memory management noise than starting it upfront while at the same time it should not increase the resume duration substantially. Accordingly, modify the code to start the async resume of the device's children when the processing of the parent has been completed in each stage of device resume and only start async resume upfront for devices without parents. Also make it check if a given device can be resumed asynchronously before starting the synchronous resume of it in case it will have to wait for another that is already resuming asynchronously. In addition to making the async resume of devices more friendly to systems with relatively less computing resources, this change is also preliminary for analogous changes in the suspend path. On the systems where it has been tested, this change by itself does not affect the overall system resume duration in a measurable way. Link: https://lore.kernel.org/linux-pm/20241114220921.2529905-1-saravanak@google.com/ [1] Signed-off-by: Rafael J. Wysocki --- drivers/base/power/main.c | 72 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 63 insertions(+), 9 deletions(-) --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -621,12 +621,41 @@ return false; } +static int dpm_async_unless_in_progress(struct device *dev, void *fn) +{ + async_func_t func = fn; + + if (!dev->power.work_in_progress) + dpm_async_fn(dev, func); + + return 0; +} + +static void dpm_async_resume_children(struct device *dev, async_func_t func) +{ + mutex_lock(&dpm_list_mtx); + + /* + * Start processing "async" children of the device unless it's been + * started already for them. + * + * This could have been done for the device's "async" consumers too, but + * they either need to wait for their parents or the processing has + * already started for them after their parents were processed. + */ + device_for_each_child(dev, func, dpm_async_unless_in_progress); + + mutex_unlock(&dpm_list_mtx); +} + static void dpm_clear_async_state(struct device *dev) { reinit_completion(&dev->power.completion); dev->power.work_in_progress = false; } +static void async_resume_noirq(void *data, async_cookie_t cookie); + /** * device_resume_noirq - Execute a "noirq resume" callback for given device. * @dev: Device to handle. @@ -710,6 +739,8 @@ dpm_save_failed_dev(dev_name(dev)); pm_dev_err(dev, state, async ? " async noirq" : " noirq", error); } + + dpm_async_resume_children(dev, async_resume_noirq); } static void async_resume_noirq(void *data, async_cookie_t cookie) @@ -733,19 +764,24 @@ mutex_lock(&dpm_list_mtx); /* - * Trigger the resume of "async" devices upfront so they don't have to - * wait for the "non-async" ones they don't depend on. + * Start processing "async" devices without parents upfront so they + * don't wait for the "sync" devices they don't depend on. */ list_for_each_entry(dev, &dpm_noirq_list, power.entry) { dpm_clear_async_state(dev); - dpm_async_fn(dev, async_resume_noirq); + if (!dev->parent) + dpm_async_fn(dev, async_resume_noirq); } while (!list_empty(&dpm_noirq_list)) { dev = to_device(dpm_noirq_list.next); list_move_tail(&dev->power.entry, &dpm_late_early_list); + dpm_async_unless_in_progress(dev, async_resume_noirq); + if (!dev->power.work_in_progress) { + dev->power.work_in_progress = true; + get_device(dev); mutex_unlock(&dpm_list_mtx); @@ -781,6 +817,8 @@ device_wakeup_disarm_wake_irqs(); } +static void async_resume_early(void *data, async_cookie_t cookie); + /** * device_resume_early - Execute an "early resume" callback for given device. * @dev: Device to handle. @@ -848,6 +886,8 @@ dpm_save_failed_dev(dev_name(dev)); pm_dev_err(dev, state, async ? " async early" : " early", error); } + + dpm_async_resume_children(dev, async_resume_early); } static void async_resume_early(void *data, async_cookie_t cookie) @@ -875,19 +915,24 @@ mutex_lock(&dpm_list_mtx); /* - * Trigger the resume of "async" devices upfront so they don't have to - * wait for the "non-async" ones they don't depend on. + * Start processing "async" devices without parents upfront so they + * don't wait for the "sync" devices they don't depend on. */ list_for_each_entry(dev, &dpm_late_early_list, power.entry) { dpm_clear_async_state(dev); - dpm_async_fn(dev, async_resume_early); + if (!dev->parent) + dpm_async_fn(dev, async_resume_early); } while (!list_empty(&dpm_late_early_list)) { dev = to_device(dpm_late_early_list.next); list_move_tail(&dev->power.entry, &dpm_suspended_list); + dpm_async_unless_in_progress(dev, async_resume_early); + if (!dev->power.work_in_progress) { + dev->power.work_in_progress = true; + get_device(dev); mutex_unlock(&dpm_list_mtx); @@ -919,6 +964,8 @@ } EXPORT_SYMBOL_GPL(dpm_resume_start); +static void async_resume(void *data, async_cookie_t cookie); + /** * device_resume - Execute "resume" callbacks for given device. * @dev: Device to handle. @@ -1012,6 +1059,8 @@ dpm_save_failed_dev(dev_name(dev)); pm_dev_err(dev, state, async ? " async" : "", error); } + + dpm_async_resume_children(dev, async_resume); } static void async_resume(void *data, async_cookie_t cookie) @@ -1043,19 +1092,24 @@ mutex_lock(&dpm_list_mtx); /* - * Trigger the resume of "async" devices upfront so they don't have to - * wait for the "non-async" ones they don't depend on. + * Start processing "async" devices without parents upfront so they + * don't wait for the "sync" devices they don't depend on. */ list_for_each_entry(dev, &dpm_suspended_list, power.entry) { dpm_clear_async_state(dev); - dpm_async_fn(dev, async_resume); + if (!dev->parent) + dpm_async_fn(dev, async_resume); } while (!list_empty(&dpm_suspended_list)) { dev = to_device(dpm_suspended_list.next); list_move_tail(&dev->power.entry, &dpm_prepared_list); + dpm_async_unless_in_progress(dev, async_resume); + if (!dev->power.work_in_progress) { + dev->power.work_in_progress = true; + get_device(dev); mutex_unlock(&dpm_list_mtx); From patchwork Tue Feb 25 16:45:31 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Rafael J. Wysocki" X-Patchwork-Id: 868388 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 D3722199FC9; Tue, 25 Feb 2025 16:46:23 +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=1740501986; cv=none; b=H0LzwkCVe7nAVdd69t1w5GXxqU5ZGHs52VqWgE4Zr5KTrwQq4+QVmpDgAwlN5iuNxFM1jhTw7oRxR0npd3/RlLPiNg8WeGS6rq1Dj5k8qZjbFInLkdoK5J24ryxl+YSUI1h96p/VjmbyFDfJ3GvC5Zyybky1LAdThzPt0eTp5v4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740501986; c=relaxed/simple; bh=/h1M9Yd/hl0peihTWu72GbT2QD7Z8SUTRbuKu4wuUVM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=j/L1yT0z80hLXDyKeaRJAfPTfZNl9oldM136zHP8cpHJouLd7x1SeruI8Upog59rLffoqs8zbDhIHLdcq7wqj6PXR1WqQsNagYbeorlSl93PHzxSRNbWOukjDc+aUIg4/+KVY+YMVywksSU4zZnDJVJcNU0WvIEHzARJY9zIdNo= 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=F32oceb9; 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="F32oceb9" 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.1) id d576d25cca437ddc; Tue, 25 Feb 2025 17:46:16 +0100 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 E50A922C28BF; Tue, 25 Feb 2025 17:46:15 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=rjwysocki.net; s=dkim; t=1740501976; bh=/h1M9Yd/hl0peihTWu72GbT2QD7Z8SUTRbuKu4wuUVM=; h=From:Subject:Date; b=F32oceb9XdzbWUceV5xaf1eeRTSsVGgFgwJOJW+5OErbIt1Mvdhv2fT63tBsBdMAO HDpyjn1xTbE1Ue+c5qm3IT41oAVMqFU2RydR8GAd5c0mlESr6gXtAgZtPSSqOQe2g6 mNGxg/nEQ8cpLf/8NwwFj9y/Z6a7RDSaG8gBBsKwYhc3F8hTO+6a2pdrR8nSzabvlt n1su8E6Hpki4bTJkgIvGILHVRB1LmPEFqGYpK7OTN9abPLKzz7AyokBrUUHW5xpJ6i sDTw8jJeqCS3Wjj0+WORaMUBjx0L84bUnu83KxH5yekzQtLzUad5nu3OKU/+z8Sllw ZTxZA+4d3m5EA== From: "Rafael J. Wysocki" To: Linux PM Cc: LKML , Alan Stern , Ulf Hansson , Johan Hovold , Manivannan Sadhasivam , Saravana Kannan Subject: [PATCH v1 4/5] PM: sleep: Start suspending parents and suppliers after subordinate suspend Date: Tue, 25 Feb 2025 17:45:31 +0100 Message-ID: <8536271.NyiUUSuA9g@rjwysocki.net> In-Reply-To: <13709135.uLZWGnKmhe@rjwysocki.net> References: <13709135.uLZWGnKmhe@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: clean X-VADE-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgdekvddvudcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfjqffogffrnfdpggftiffpkfenuceurghilhhouhhtmecuudehtdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurhephffvvefufffkjghfggfgtgesthfuredttddtjeenucfhrhhomhepfdftrghfrggvlhculfdrucghhihsohgtkhhifdcuoehrjhifsehrjhifhihsohgtkhhirdhnvghtqeenucggtffrrghtthgvrhhnpedvffeuiedtgfdvtddugeeujedtffetteegfeekffdvfedttddtuefhgeefvdejhfenucfkphepudelhedrudefiedrudelrdelgeenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepihhnvghtpeduleehrddufeeirdduledrleegpdhhvghlohepkhhrvggrtghhvghrrdhlohgtrghlnhgvthdpmhgrihhlfhhrohhmpehrjhifsehrjhifhihsohgtkhhirdhnvghtpdhnsggprhgtphhtthhopeejpdhrtghpthhtoheplhhinhhugidqphhmsehvghgvrhdrkhgvrhhnvghlrdhorhhgpdhrtghpthhtoheplhhinhhugidqkhgvrhhnvghlsehvghgvrhdrkhgvrhhnvghlrdhorhhgpdhrtghpthhtohepshhtvghrnhesrhhofihlrghnugdrhhgrrhhvrghrugdrvgguuhdprhgtphhtthhopehulhhfrdhhrghnshhsohhnsehlihhnrghrohdrohhrghdprhgtphhtthhopehjohhhrghnsehkvghrnhgvlhdrohhrghdprhgtphh X-DCC--Metrics: v370.home.net.pl 1024; Body=7 Fuz1=7 Fuz2=7 From: Rafael J. Wysocki In analogy with the previous change affecting the resume path, make device_suspend() start the async suspend of the device's parent and suppliers after the device itself has been processed and make dpm_suspend() start processing "async" leaf devices (that is, devices without children or consumers) upfront because they don't need to wait for any other devices. On the Dell XPS13 9360 in my office, this change reduces the total duration of device suspend by approximately 100 ms (over 20%). Signed-off-by: Rafael J. Wysocki --- drivers/base/power/main.c | 73 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 4 deletions(-) --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -1237,6 +1237,49 @@ /*------------------------- Suspend routines -------------------------*/ +static bool dpm_leaf_device(struct device *dev) +{ + struct device *child; + + lockdep_assert_held(&dpm_list_mtx); + + child = device_find_any_child(dev); + if (child) { + put_device(child); + + return false; + } + + /* + * Since this function is required to run under dpm_list_mtx, the + * list_empty() below will only return true if the device's list of + * consumers is actually empty before calling it. + */ + return list_empty(&dev->links.consumers); +} + +static void dpm_async_suspend_superior(struct device *dev, async_func_t func) +{ + struct device_link *link; + + mutex_lock(&dpm_list_mtx); + + /* Start processing the device's parent if it is "async". */ + if (dev->parent) + dpm_async_unless_in_progress(dev->parent, func); + + /* + * Start processing the device's "async" suppliers. + * + * The dpm_list_mtx locking is sufficient for this. + */ + list_for_each_entry_rcu(link, &dev->links.consumers, s_node) + if (READ_ONCE(link->status) != DL_STATE_DORMANT) + dpm_async_unless_in_progress(link->consumer, func); + + mutex_unlock(&dpm_list_mtx); +} + /** * resume_event - Return a "resume" message for given "suspend" sleep state. * @sleep_state: PM message representing a sleep state. @@ -1663,6 +1706,8 @@ device_links_read_unlock(idx); } +static void async_suspend(void *data, async_cookie_t cookie); + /** * device_suspend - Execute "suspend" callbacks for given device. * @dev: Device to handle. @@ -1791,7 +1836,13 @@ complete_all(&dev->power.completion); TRACE_SUSPEND(error); - return error; + + if (error || async_error) + return error; + + dpm_async_suspend_superior(dev, async_suspend); + + return 0; } static void async_suspend(void *data, async_cookie_t cookie) @@ -1809,6 +1860,7 @@ int dpm_suspend(pm_message_t state) { ktime_t starttime = ktime_get(); + struct device *dev; int error = 0; trace_suspend_resume(TPS("dpm_suspend"), state.event, true); @@ -1822,15 +1874,28 @@ mutex_lock(&dpm_list_mtx); + /* + * Start processing "async" leaf devices upfront because they don't need + * to wait. + */ + list_for_each_entry_reverse(dev, &dpm_prepared_list, power.entry) { + dpm_clear_async_state(dev); + if (dpm_leaf_device(dev)) + dpm_async_fn(dev, async_suspend); + } + while (!list_empty(&dpm_prepared_list)) { - struct device *dev = to_device(dpm_prepared_list.prev); + dev = to_device(dpm_prepared_list.prev); list_move(&dev->power.entry, &dpm_suspended_list); - dpm_clear_async_state(dev); - if (dpm_async_fn(dev, async_suspend)) + dpm_async_unless_in_progress(dev, async_suspend); + + if (dev->power.work_in_progress) continue; + dev->power.work_in_progress = true; + get_device(dev); mutex_unlock(&dpm_list_mtx); From patchwork Tue Feb 25 16:45:37 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Rafael J. Wysocki" X-Patchwork-Id: 868867 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 E6BE4199E88; Tue, 25 Feb 2025 16:46:22 +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=1740501986; cv=none; b=EQLvvodEYYsFy58KCtUYLI0Pg7Pi9LswWjhnBU7FAZF56Hdt3xRXK29+7eoc6HhQ4oxn1Ak4fGRBUPWA1eVvpR+LCZ7K1oIsNLAdWxEzxp2fzjN+rEaamU4iXjDysBIRJ4V34weRGAjEmBeSD7hXfGsrExrQevUYLaEbHlpenKQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740501986; c=relaxed/simple; bh=/Bl7bGe++8isDlcz6Yj2CRmk4+9xThGrSHZAAT8K00E=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=mczRtXTxsUWLkCTiuokh8UP9Zb6gbCVLpvKynIRZ/Y26ubgZXGH7HQrhulBSv0agx+b0KfJLKLYWVZ/oH+01NlUtVNiTCacmjV6fjRWq6sZ09yjiWTKM9ZZg3cq3t33+dgkq/EanMmjriSL7t6L6AL0WyZtUDFO1c7NhQ+dS7KA= 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=DerIyJ8c; 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="DerIyJ8c" 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.1) id d0c76005e8e4e746; Tue, 25 Feb 2025 17:46:15 +0100 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 0AA6622C28BF; Tue, 25 Feb 2025 17:46:15 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=rjwysocki.net; s=dkim; t=1740501975; bh=/Bl7bGe++8isDlcz6Yj2CRmk4+9xThGrSHZAAT8K00E=; h=From:Subject:Date; b=DerIyJ8cOL8sFe0ssqaBLAhjptKb0jb+awo4bNfQCj8BMmtKGyQjTH2dMWFOL9o+G FOv5nXZugVANCRDq1KTNw+O/4WTow7dMhMkAKBrSpedXxMET8I41PtnmffvVCWBH6r WAHs83oGhiKEeK0ea45WVqTB8K48y7Q9w3VJPNiKLpeTse9umHhkAjebdAek4kpYHw vyPSpa6NtdkWm0oKSipvou5+O/kYASjV8uOad/TdAri4bUtJl15XR0XsOTD9SeIv62 r1A9SPyCOMjPs3dH2XF0MZetmt44+f0Zti115u2pNVtznIRJSCxXdu7QnJTyyPq9FJ K3iKFaWsOCqAQ== From: "Rafael J. Wysocki" To: Linux PM Cc: LKML , Alan Stern , Ulf Hansson , Johan Hovold , Manivannan Sadhasivam , Saravana Kannan Subject: [PATCH v1 5/5] PM: sleep: Make late and noirq suspend of devices more asynchronous Date: Tue, 25 Feb 2025 17:45:37 +0100 Message-ID: <2016539.usQuhbGJ8B@rjwysocki.net> In-Reply-To: <13709135.uLZWGnKmhe@rjwysocki.net> References: <13709135.uLZWGnKmhe@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: clean X-VADE-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgdekvddvvdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfjqffogffrnfdpggftiffpkfenuceurghilhhouhhtmecuudehtdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurhephffvvefufffkjghfggfgtgesthfuredttddtjeenucfhrhhomhepfdftrghfrggvlhculfdrucghhihsohgtkhhifdcuoehrjhifsehrjhifhihsohgtkhhirdhnvghtqeenucggtffrrghtthgvrhhnpedvffeuiedtgfdvtddugeeujedtffetteegfeekffdvfedttddtuefhgeefvdejhfenucfkphepudelhedrudefiedrudelrdelgeenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepihhnvghtpeduleehrddufeeirdduledrleegpdhhvghlohepkhhrvggrtghhvghrrdhlohgtrghlnhgvthdpmhgrihhlfhhrohhmpehrjhifsehrjhifhihsohgtkhhirdhnvghtpdhnsggprhgtphhtthhopeejpdhrtghpthhtoheplhhinhhugidqphhmsehvghgvrhdrkhgvrhhnvghlrdhorhhgpdhrtghpthhtoheplhhinhhugidqkhgvrhhnvghlsehvghgvrhdrkhgvrhhnvghlrdhorhhgpdhrtghpthhtohepshhtvghrnhesrhhofihlrghnugdrhhgrrhhvrghrugdrvgguuhdprhgtphhtthhopehulhhfrdhhrghnshhsohhnsehlihhnrghrohdrohhrghdprhgtphhtthhopehjohhhrghnsehkvghrnhgvlhdrohhrghdprhgtphh X-DCC--Metrics: v370.home.net.pl 1024; Body=7 Fuz1=7 Fuz2=7 From: Rafael J. Wysocki In analogy with previous changes, make device_suspend_late() and device_suspend_noirq() start the async suspend of the device's parent and suppliers after the device itself has been processed and make dpm_suspend_late() and dpm_noirq_suspend_devices() start processing "async" leaf devices (that is, devices without children or consumers) upfront because they don't need to wait for any other devices. Signed-off-by: Rafael J. Wysocki --- drivers/base/power/main.c | 60 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 8 deletions(-) --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -1317,6 +1317,8 @@ device_links_read_unlock(idx); } +static void async_suspend_noirq(void *data, async_cookie_t cookie); + /** * device_suspend_noirq - Execute a "noirq suspend" callback for given device. * @dev: Device to handle. @@ -1396,7 +1398,13 @@ Complete: complete_all(&dev->power.completion); TRACE_SUSPEND(error); - return error; + + if (error || async_error) + return error; + + dpm_async_suspend_superior(dev, async_suspend_noirq); + + return 0; } static void async_suspend_noirq(void *data, async_cookie_t cookie) @@ -1410,6 +1418,7 @@ static int dpm_noirq_suspend_devices(pm_message_t state) { ktime_t starttime = ktime_get(); + struct device *dev; int error = 0; trace_suspend_resume(TPS("dpm_suspend_noirq"), state.event, true); @@ -1419,15 +1428,28 @@ mutex_lock(&dpm_list_mtx); + /* + * Start processing "async" leaf devices upfront because they don't need + * to wait. + */ + list_for_each_entry_reverse(dev, &dpm_late_early_list, power.entry) { + dpm_clear_async_state(dev); + if (dpm_leaf_device(dev)) + dpm_async_fn(dev, async_suspend_noirq); + } + while (!list_empty(&dpm_late_early_list)) { - struct device *dev = to_device(dpm_late_early_list.prev); + dev = to_device(dpm_late_early_list.prev); list_move(&dev->power.entry, &dpm_noirq_list); - dpm_clear_async_state(dev); - if (dpm_async_fn(dev, async_suspend_noirq)) + dpm_async_unless_in_progress(dev, async_suspend_noirq); + + if (dev->power.work_in_progress) continue; + dev->power.work_in_progress = true; + get_device(dev); mutex_unlock(&dpm_list_mtx); @@ -1492,6 +1514,8 @@ spin_unlock_irq(&parent->power.lock); } +static void async_suspend_late(void *data, async_cookie_t cookie); + /** * device_suspend_late - Execute a "late suspend" callback for given device. * @dev: Device to handle. @@ -1568,7 +1592,13 @@ Complete: TRACE_SUSPEND(error); complete_all(&dev->power.completion); - return error; + + if (error || async_error) + return error; + + dpm_async_suspend_superior(dev, async_suspend_late); + + return 0; } static void async_suspend_late(void *data, async_cookie_t cookie) @@ -1586,6 +1616,7 @@ int dpm_suspend_late(pm_message_t state) { ktime_t starttime = ktime_get(); + struct device *dev; int error = 0; trace_suspend_resume(TPS("dpm_suspend_late"), state.event, true); @@ -1597,15 +1628,28 @@ mutex_lock(&dpm_list_mtx); + /* + * Start processing "async" leaf devices upfront because they don't need + * to wait. + */ + list_for_each_entry_reverse(dev, &dpm_suspended_list, power.entry) { + dpm_clear_async_state(dev); + if (dpm_leaf_device(dev)) + dpm_async_fn(dev, async_suspend_late); + } + while (!list_empty(&dpm_suspended_list)) { - struct device *dev = to_device(dpm_suspended_list.prev); + dev = to_device(dpm_suspended_list.prev); list_move(&dev->power.entry, &dpm_late_early_list); - dpm_clear_async_state(dev); - if (dpm_async_fn(dev, async_suspend_late)) + dpm_async_unless_in_progress(dev, async_suspend_late); + + if (dev->power.work_in_progress) continue; + dev->power.work_in_progress = true; + get_device(dev); mutex_unlock(&dpm_list_mtx);