Received: by 2002:a05:6a10:a0d1:0:0:0:0 with SMTP id j17csp425431pxa; Fri, 21 Aug 2020 10:44:54 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz9wgT/aKXEZ4w5dFVb3sGz9TGrIHuRuKGoPjqWlEwosOA3GSHxWNOVzIXP2pcU2EPIVK5C X-Received: by 2002:a17:906:2b57:: with SMTP id b23mr3942079ejg.26.1598031894367; Fri, 21 Aug 2020 10:44:54 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1598031894; cv=none; d=google.com; s=arc-20160816; b=XQuAOj+kfBBZFyoi0qHJdyxlOhgIQG0lXQFrMxyYtGs8QYaQadwHIx1egyxwkXsxyB 3nFFnavov6BcelxsPtrUKL+PC/b69odE8QITjDqdPvWtzOJ0T1tPndiC8Lew3wnSlIUN GHS3dEsAKvtiDDUmQfYxGvse/+dE+U3YKIPSLYkhnloibGzXUgeQ2D5bYlaUS/V6UP2B uOtl6qZ4WN/nvnNRptk2xCQ6XMHRSUIpgLc1Ya1650Wgy7VTIv2NfcYUrlbP5n00ytzm OzweGl6+zfpDLxLxgjCWXG7n8v9Nbr3HSNi/MNt7PugAq+yBiHXWsySP3IyGBGK6Qg+W Rakw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from; bh=lFqdqaNbtCox6QmxMYABz8/xx6rxIpwxeerAo+DGqGU=; b=ttSbNFB6SAHfQJa5n4n6OIO0JIO1dmW+ZZZDg7ItAspFhkASo4CZd6dnevXE26fXVo yw2aDB7LfvHTpQkHLn4r+IkR7NZsTr8zZqzqSOv7+/6WJb20mzgfFZdEZ4+8KSXWHka1 kDjk7aAI88nvmltpgEQwdBjtDOn8W1X5p696pNZX+xZekNDHYc64ulPCZDwoNcQlVMoi HHBfetm2EYTBKYgXfcRGOI6OGzMEueCyZMmYkWABB8mCxb7VNqmHd7xSmXVqtw1d2lW7 /J0G2t9FPgrBt+wTzQU2ZVOoYU7TXswTKEKVdTOY1+G+IlzeOEu0TkJ2b6Myicg5ZCrt 7O5w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id v24si1708670edl.35.2020.08.21.10.44.31; Fri, 21 Aug 2020 10:44:54 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726864AbgHURlJ (ORCPT + 99 others); Fri, 21 Aug 2020 13:41:09 -0400 Received: from cloudserver094114.home.pl ([79.96.170.134]:41928 "EHLO cloudserver094114.home.pl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725885AbgHURlE (ORCPT ); Fri, 21 Aug 2020 13:41:04 -0400 Received: from 89-64-88-37.dynamic.chello.pl (89.64.88.37) (HELO kreacher.localnet) by serwer1319399.home.pl (79.96.170.134) with SMTP (IdeaSmtpServer 0.83.459) id 84c0e64bc6fbadae; Fri, 21 Aug 2020 19:41:02 +0200 From: "Rafael J. Wysocki" To: Linux PM Cc: LKML , Linux ACPI , Greg Kroah-Hartman , "Rafael J. Wysocki" , Mika Westerberg , Alan Stern Subject: [PATCH] PM: sleep: core: Fix the handling of pending runtime resume requests Date: Fri, 21 Aug 2020 19:41:02 +0200 Message-ID: <7969920.MVx1BpXlEM@kreacher> MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Rafael J. Wysocki 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, if there is a pending runtime resume request for a device while __device_suspend() is running for it, the physical state of the device may not be in agreement with the "suspended" runtime PM status of it (which may be the very reason for queuing up the runtime resume request for it). For these reasons, rework __device_suspend() to carry out synchronous runtime-resume for devices with pending runtime resume requests before attempting to invoke system-wide suspend callbacks for them with the expectation that their drivers will trigger system-wide wakeup events in the process of handling the runtime resume, if necessary. Fixes: 1e2ef05bb8cf8 ("PM: Limit race conditions between runtime PM and system sleep (v2)") Reported-by: Mika Westerberg Signed-off-by: Rafael J. Wysocki --- drivers/base/power/main.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) Index: linux-pm/drivers/base/power/main.c =================================================================== --- linux-pm.orig/drivers/base/power/main.c +++ linux-pm/drivers/base/power/main.c @@ -1606,13 +1606,13 @@ 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. + * If there's a runtime resume request pending for the device, resume + * it before proceeding with invoking the system-wide suspend callbacks + * for it, because the physical state of the device may not reflect the + * "suspended" runtime PM status already in that case. */ - if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) - pm_wakeup_event(dev, 0); + if (pm_runtime_barrier(dev)) + pm_runtime_resume(dev); if (pm_wakeup_pending()) { dev->power.direct_complete = false;