From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 16F76C433E2 for ; Tue, 1 Sep 2020 15:48:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E7AF62064B for ; Tue, 1 Sep 2020 15:48:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598975314; bh=t1WLS8EBNDQ55XLUQkg96xIlVp4iWCrQvJynvhjL1KA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=QDpYBiZb64HOx2PgsPrCYrsqKLXP4cgf0K7FXIMU0xHE0KYVuJ+QV99qGidTh637O BIa60Jjaqn+0v0fMz4FFrnC/D3tVAYNLzINQXMF46BZV7jw5yZ/px5AN+LQdPfSpNm W3XUQUvppyHcRhpH7L59pi0o0t4l8C7d5evXuQuA= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728387AbgIAPsa (ORCPT ); Tue, 1 Sep 2020 11:48:30 -0400 Received: from mail.kernel.org ([198.145.29.99]:60192 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731817AbgIAPoh (ORCPT ); Tue, 1 Sep 2020 11:44:37 -0400 Received: from localhost (83-86-74-64.cable.dynamic.v4.ziggo.nl [83.86.74.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 6B100206FA; Tue, 1 Sep 2020 15:44:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598975077; bh=t1WLS8EBNDQ55XLUQkg96xIlVp4iWCrQvJynvhjL1KA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jG1wH9QAQuaYh7s4kpK2J7i+/rPUmJEUt5yC9F2p6DgKQD7ErnG4Uvt6hyHLX3bNz E846ReTJJ3cNtVu5RzB/77aIWu3O0zgzmFiIlzBWx8MJRwIcziKD/V9Daq7ryTiswK vpesCwc6eelNY2I7NbAcinEyU9bIQaouhxMq8CmY= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, "Rafael J. Wysocki" , Alan Stern , Utkarsh H Patel , Pengfei Xu Subject: [PATCH 5.8 200/255] PM: sleep: core: Fix the handling of pending runtime resume requests Date: Tue, 1 Sep 2020 17:10:56 +0200 Message-Id: <20200901151010.277903525@linuxfoundation.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200901151000.800754757@linuxfoundation.org> References: <20200901151000.800754757@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Rafael J. Wysocki commit e3eb6e8fba65094328b8dca635d00de74ba75b45 upstream. It has been reported that system-wide suspend may be aborted in the absence of any wakeup events due to unforseen interactions of it with the runtume PM framework. One failing scenario is when there are multiple devices sharing an ACPI power resource and runtime-resume needs to be carried out for one of them during system-wide suspend (for example, because it needs to be reconfigured before the whole system goes to sleep). In that case, the runtime-resume of that device involves turning the ACPI power resource "on" which in turn causes runtime-resume requests to be queued up for all of the other devices sharing it. Those requests go to the runtime PM workqueue which is frozen during system-wide suspend, so they are not actually taken care of until the resume of the whole system, but the pm_runtime_barrier() call in __device_suspend() sees them and triggers system wakeup events for them which then cause the system-wide suspend to be aborted if wakeup source objects are in active use. Of course, the logic that leads to triggering those wakeup events is questionable in the first place, because clearly there are cases in which a pending runtime resume request for a device is not connected to any real wakeup events in any way (like the one above). Moreover, it is racy, because the device may be resuming already by the time the pm_runtime_barrier() runs and so if the driver doesn't take care of signaling the wakeup event as appropriate, it will be lost. However, if the driver does take care of that, the extra pm_wakeup_event() call in the core is redundant. Accordingly, drop the conditional pm_wakeup_event() call fron __device_suspend() and make the latter call pm_runtime_barrier() alone. Also modify the comment next to that call to reflect the new code and extend it to mention the need to avoid unwanted interactions between runtime PM and system-wide device suspend callbacks. Fixes: 1e2ef05bb8cf8 ("PM: Limit race conditions between runtime PM and system sleep (v2)") Signed-off-by: Rafael J. Wysocki Acked-by: Alan Stern Reported-by: Utkarsh H Patel Tested-by: Utkarsh H Patel Tested-by: Pengfei Xu Cc: All applicable Signed-off-by: Greg Kroah-Hartman --- drivers/base/power/main.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -1606,13 +1606,17 @@ static int __device_suspend(struct devic } /* - * If a device configured to wake up the system from sleep states - * has been suspended at run time and there's a resume request pending - * for it, this is equivalent to the device signaling wakeup, so the - * system suspend operation should be aborted. + * Wait for possible runtime PM transitions of the device in progress + * to complete and if there's a runtime resume request pending for it, + * resume it before proceeding with invoking the system-wide suspend + * callbacks for it. + * + * If the system-wide suspend callbacks below change the configuration + * of the device, they must disable runtime PM for it or otherwise + * ensure that its runtime-resume callbacks will not be confused by that + * change in case they are invoked going forward. */ - if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) - pm_wakeup_event(dev, 0); + pm_runtime_barrier(dev); if (pm_wakeup_pending()) { dev->power.direct_complete = false;