Received: by 2002:ac0:8845:0:0:0:0:0 with SMTP id g63csp27956img; Wed, 27 Feb 2019 15:59:47 -0800 (PST) X-Google-Smtp-Source: AHgI3IbWJEq4s/F0JQ8vFXUX+a8DxWdIQgkIt2CKXagRWn5+X/qa1hVFS2JJ3Y5NDY7ticxcr5+v X-Received: by 2002:a17:902:461:: with SMTP id 88mr4892016ple.216.1551311987081; Wed, 27 Feb 2019 15:59:47 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1551311987; cv=none; d=google.com; s=arc-20160816; b=pGQcCa5LxfuUjzFG6Y29ypKD6qI9cF0LehvPQfoB9No9SUOKrgEHSlXoWG9e55MeJQ +aiUjVtBIICsVk8BJd4fkcQj3cl3eicVu9kVWGJ9rY0X+/GzP1KpZGRkgigEZJdklwnz KVphejzv28mPPTT7L7BdIyZ9uhCCBy0PhJEdAirHgOMTaGe/OvSTwq7jZNoN5v3Zbgx3 x6zSVYrQlP6eh4R3JvRSncZsqRfbOzkoGYPa90FAFIb4O8m6HdLWTxTNXDzgl8Lqwc6t NPKZuUt2wufGKGFNyv/06RtUlGlggde5eiJJlhis59ZG18Pi1LrohSYuty1XbFuBNsd7 Gu9Q== 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=qk7Tinuo2ntUJDVeycULsiZ4OVCV28kjie1+W8XOkvY=; b=mcOfWLjonafwCMdws24yDumJLlGqu32VTST26AvN8rezkSaGXzdakYvQtUjzxsbEbE Mli3ozi5YNbT4Lg5BWfNTywyrgQFc6RSjuuQ/IKBlSgL1xvoaGbZGxXjdSpEbDDvCz6y +pYezp82lnmXvIPieyDhT46Y4cMr0E3JWYaLz+De8mdZcSP/4nr4AAm0hmpyEqNrndGB JLKAwePuL6cQN54VSfgEKCJ39UPeZjevoh4JIPteqqzDkOM78kllpt1yTuOBVjI00vV5 dPZ0jcKiDj0gYqmGfWMhx9HN2EiBuL+s1fSNU0P2QhOq56z31ld+t4iCohbpM50IiEKr hCmw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id j2si15251495pgp.418.2019.02.27.15.59.31; Wed, 27 Feb 2019 15:59:47 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730410AbfB0X6R (ORCPT + 99 others); Wed, 27 Feb 2019 18:58:17 -0500 Received: from cloudserver094114.home.pl ([79.96.170.134]:44682 "EHLO cloudserver094114.home.pl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728397AbfB0X6Q (ORCPT ); Wed, 27 Feb 2019 18:58:16 -0500 Received: from 79.184.254.15.ipv4.supernova.orange.pl (79.184.254.15) (HELO aspire.rjw.lan) by serwer1319399.home.pl (79.96.170.134) with SMTP (IdeaSmtpServer 0.83.213) id b2b9c462b15c26e4; Thu, 28 Feb 2019 00:58:14 +0100 From: "Rafael J. Wysocki" To: Bjorn Helgaas Cc: Dongdong Liu , Lukas Wunner , Linux PCI , Linux PM , LKML Subject: [PATCH] PCI: PCIe: PME: Fix pcie_pme_remove() Date: Thu, 28 Feb 2019 00:56:41 +0100 Message-ID: <1943648.NMEmlssb0J@aspire.rjw.lan> 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 is incorrect to call pcie_pme_suspend() from pcie_pme_remove() for two reasons. First, pcie_pme_suspend() calls synchronize_irq() that will wait for the native hotplug interrupt handler as well as for the PME one, because they share one IRQ (as per the spec). That may deadlock if hotplug is signaled while pcie_pme_remove() is running and the latter calls pci_lock_rescan_remove() before the former. Second, if pcie_pme_suspend() figures out that wakeup needs to be enabled for the port, it will return without disabling the interrupt as expected by pcie_pme_remove() which was overlooked by commit c7b5a4e6e8fb ("PCI / PM: Fix native PME handling during system suspend/resume"). To fix that, rework pcie_pme_remove() to disable the PME interrupt, clear its status and prevent the PME worker function from re-enabling it before calling free_irq() on it which should be sufficient. Fixes: c7b5a4e6e8fb ("PCI / PM: Fix native PME handling during system suspend/resume") Reported-by: Dongdong Liu Signed-off-by: Rafael J. Wysocki --- drivers/pci/pcie/pme.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) Index: linux-pm/drivers/pci/pcie/pme.c =================================================================== --- linux-pm.orig/drivers/pci/pcie/pme.c +++ linux-pm/drivers/pci/pcie/pme.c @@ -363,6 +363,16 @@ static bool pcie_pme_check_wakeup(struct return false; } +static void pcie_pme_disable_interrupt(struct pci_dev *port, + struct pcie_pme_service_data *data) +{ + spin_lock_irq(&data->lock); + pcie_pme_interrupt_enable(port, false); + pcie_clear_root_pme_status(port); + data->noirq = true; + spin_unlock_irq(&data->lock); +} + /** * pcie_pme_suspend - Suspend PCIe PME service device. * @srv: PCIe service device to suspend. @@ -387,11 +397,7 @@ static int pcie_pme_suspend(struct pcie_ return 0; } - spin_lock_irq(&data->lock); - pcie_pme_interrupt_enable(port, false); - pcie_clear_root_pme_status(port); - data->noirq = true; - spin_unlock_irq(&data->lock); + pcie_pme_disable_interrupt(port, data); synchronize_irq(srv->irq); @@ -427,9 +433,11 @@ static int pcie_pme_resume(struct pcie_d */ static void pcie_pme_remove(struct pcie_device *srv) { - pcie_pme_suspend(srv); + struct pcie_pme_service_data *data = get_service_data(srv); + + pcie_pme_disable_interrupt(srv->port, data); free_irq(srv->irq, srv); - kfree(get_service_data(srv)); + kfree(data); } static int pcie_pme_runtime_suspend(struct pcie_device *srv)