From patchwork Thu Oct 27 16:05:34 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Norris X-Patchwork-Id: 9399841 X-Patchwork-Delegate: rjw@sisk.pl 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 2D2F560588 for ; Thu, 27 Oct 2016 16:06:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 19B2D2A2AE for ; Thu, 27 Oct 2016 16:06:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0D0C22A351; Thu, 27 Oct 2016 16:06:11 +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 1AA5D2A2AE for ; Thu, 27 Oct 2016 16:06:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S937770AbcJ0QGG (ORCPT ); Thu, 27 Oct 2016 12:06:06 -0400 Received: from mail-pf0-f174.google.com ([209.85.192.174]:36835 "EHLO mail-pf0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S942012AbcJ0QFu (ORCPT ); Thu, 27 Oct 2016 12:05:50 -0400 Received: by mail-pf0-f174.google.com with SMTP id e6so20334511pfk.3 for ; Thu, 27 Oct 2016 09:05:50 -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=fVat2R0oyBQ05Z4g+2KtOE81Luw//HU3kQtgrV7lfKM=; b=SZvfPK37NXrPYvGnTI3tiiQ4v/sPvfCi2WN0WzqpATEnTTs2g6jm0qVzSZ6ZKby22X xyRQOiCJEgPPPB/3mGZf+OnhINrLWhcGD6sTT450WUS1/IwkRKYR+kH9idDlq3OoeUdM CppFWknXtAgrgDFvyjxQ6QoQfTy9TqMxDXqMg= 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=fVat2R0oyBQ05Z4g+2KtOE81Luw//HU3kQtgrV7lfKM=; b=adxUDqixueyBkcCsFsR1wMIQ1VCWJXYbQ7t9pJhp/Y6iSruyNXb3NjHLBs3JDfxLr9 OCH9pXdVT/yy1uSqi8ApXAk1C7Ux0FV4ZwCkuBBzBAn8GKKLXp2WoZpFb+GoLLBNq82p YIk3d2wXFYpXU0sPtco19gYHEYqsGgyJNhpe6xk3W4I2F2xclfX+aAuv9d3fIy5c4RFs ORkAFsXDg17jJ6ust1LHQW2lFi08YUJoeZOvssGkVnG6RTL9pbiIihFXY1gJZM7Jym5F meFAAVmOx1u5KB9xmMrNBVwiTVeESxoNUPcpaulZuIon+xP4Lu2larak7mA8fyCLYLvm iOjQ== X-Gm-Message-State: ABUngvd9TyvmNci1Mc2YprweU8KP7iCSkte3vJC5AmlHyBdkzdiU/k7mgxWRMIOdbMOElybn X-Received: by 10.98.7.148 with SMTP id 20mr16050019pfh.18.1477584349582; Thu, 27 Oct 2016 09:05:49 -0700 (PDT) Received: from ban.mtv.corp.google.com ([172.22.64.120]) by smtp.gmail.com with ESMTPSA id 141sm12814705pfw.63.2016.10.27.09.05.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 27 Oct 2016 09:05:49 -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 v2 2/2] PM / sleep: don't suspend parent when async child suspend_{noirq, late} fails Date: Thu, 27 Oct 2016 09:05:34 -0700 Message-Id: <1477584334-39956-1-git-send-email-briannorris@chromium.org> X-Mailer: git-send-email 2.8.0.rc3.226.g39d4020 In-Reply-To: <1476923170-111986-2-git-send-email-briannorris@chromium.org> References: <1476923170-111986-2-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_late(), 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_late() 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 --- v2: s/early/late/ in commit message 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);