From patchwork Thu Oct 20 00:26:10 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Norris X-Patchwork-Id: 9385623 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 0D124608A7 for ; Thu, 20 Oct 2016 00:26:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0299429002 for ; Thu, 20 Oct 2016 00:26:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EB6232902C; Thu, 20 Oct 2016 00:26:52 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8210029028 for ; Thu, 20 Oct 2016 00:26:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753481AbcJTA0v (ORCPT ); Wed, 19 Oct 2016 20:26:51 -0400 Received: from mail-pf0-f175.google.com ([209.85.192.175]:36300 "EHLO mail-pf0-f175.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753595AbcJTA0t (ORCPT ); Wed, 19 Oct 2016 20:26:49 -0400 Received: by mail-pf0-f175.google.com with SMTP id e6so24606290pfk.3 for ; Wed, 19 Oct 2016 17:26:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=mQpDxbSllJ/LyKv+mtZoDMy8Eukbm70FDX9JwJFOS/A=; b=MIecLAYrvHip4Ad7hp7zS5Oqtu26TRMCrNA4QgFTMLptx64e7LDaLCVC0P/ZOTMYLp QK1i0lLWdT7fbL2dJA8rUeyWTdMnKK4eXflwg+OwR59DxVVP3nhDUJ5+B5VHcC8utQZy aQj+6LepiKIeFOBYecHvurFV1dG4aS8WNm0rY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=mQpDxbSllJ/LyKv+mtZoDMy8Eukbm70FDX9JwJFOS/A=; b=cp4B5JLP04lDv33DoMICQcFz/SQN/wmtI8lafijucfVMommDTjdqoWcSMr0SDjfSTg P+JfkDEVhZafL52yB6DxSHwCSrjOjgkvCiWNfQsZ6eHvlNq1LgyoSSFvZYZ19vGIgvBx ftf2HqmzaIXkSiv57AfOECpqfLTbBPcRZQWI+v/Gbvr93YMoQkBuhwHmkRMwITp6igJT clJuGOoBzLfL8OEAQZWfCaMH79XCGzFIn5OSxwT1hGJzofP7BeJhH9VZNAXB18erZkZg TCbI9WkVRjNxCdID/6762iFVtEVAbsaxeu8ON6Bxu6FXk6NlLDCrTVU3hOkARIXkjZjL xq+A== X-Gm-Message-State: AA6/9RnwZxJHmTLRF/U2xKd3zNg681vZMD6E+721X7EZipb9GC9kdhcuzNm4FE6LgL24dsEu X-Received: by 10.99.121.2 with SMTP id u2mr13163119pgc.141.1476923208831; Wed, 19 Oct 2016 17:26:48 -0700 (PDT) Received: from ban.mtv.corp.google.com ([172.22.64.120]) by smtp.gmail.com with ESMTPSA id b139sm44359287pfb.8.2016.10.19.17.26.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 19 Oct 2016 17:26:48 -0700 (PDT) From: Brian Norris To: "Rafael J . Wysocki" , Pavel Machek , Len Brown , Greg Kroah-Hartman Cc: , Doug Anderson , Brian Norris , Jeffy Chen , linux-pm@vger.kernel.org, Chuansheng Liu , Dmitry Torokhov , Brian Norris Subject: [PATCH 2/2] PM / sleep: don't suspend parent when async child suspend_{noirq, early} fails Date: Wed, 19 Oct 2016 17:26:10 -0700 Message-Id: <1476923170-111986-2-git-send-email-briannorris@chromium.org> X-Mailer: git-send-email 2.8.0.rc3.226.g39d4020 In-Reply-To: <1476923170-111986-1-git-send-email-briannorris@chromium.org> References: <1476923170-111986-1-git-send-email-briannorris@chromium.org> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Consider two devices, A and B, where B is a child of A, and B utilizes asynchronous suspend (it does not matter whether A is sync or async). If B fails to suspend_noirq() or suspend_early(), or is interrupted by a wakeup (pm_wakeup_pending()), then it aborts and sets the async_error variable. However, device A does not (immediately) check the async_error variable; it may continue to run its own suspend_noirq()/suspend_early() callback. This is bad. We can resolve this problem by checking the async_error flag after waiting for children to suspend, using the same logic for the noirq and late suspend cases as we already do for __device_suspend(). It's easy to observe this erroneous behavior by, for example, forcing a device to sleep a bit in its suspend_noirq() (to ensure the parent is waiting for the child to complete), then return an error, and watch the parent suspend_noirq() still get called. (Or similarly, fake a wakeup event at the right (or is it wrong?) time.) Fixes: de377b397272 ("PM / sleep: Asynchronous threads for suspend_late") Fixes: 28b6fd6e3779 ("PM / sleep: Asynchronous threads for suspend_noirq") Reported-by: Jeffy Chen Signed-off-by: Brian Norris Reviewed-by: Dmitry Torokhov --- Tested mostly on 4.4, but the code (and seemingly the bug) is mostly untouched since then. I can try to conjure up a proper upstream test if required. drivers/base/power/main.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index c58563581345..eaf6b53463a5 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -1040,6 +1040,9 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a dpm_wait_for_children(dev, async); + if (async_error) + goto Complete; + if (dev->pm_domain) { info = "noirq power domain "; callback = pm_noirq_op(&dev->pm_domain->ops, state); @@ -1187,6 +1190,9 @@ static int __device_suspend_late(struct device *dev, pm_message_t state, bool as dpm_wait_for_children(dev, async); + if (async_error) + goto Complete; + if (dev->pm_domain) { info = "late power domain "; callback = pm_late_early_op(&dev->pm_domain->ops, state);