Received: by 2002:a05:6a10:c604:0:0:0:0 with SMTP id y4csp2747230pxt; Mon, 9 Aug 2021 08:02:11 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxwEWiPDnr/ro8dLUlYPg68CNhyRg1/MTvzs+OfZKIcjoYUo6ziNBLJZVmFqTbH5qXg4EYU X-Received: by 2002:a5e:a907:: with SMTP id c7mr296919iod.46.1628521330785; Mon, 09 Aug 2021 08:02:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1628521330; cv=none; d=google.com; s=arc-20160816; b=PXTZVgGoUzQczDY5lZ2XArRp7BmdbemmCtB2qms9XuYa7Vb9jjtbV5O1fqDgsi1TWh 7GnHjO7PI55t0vsfK83km4NnYlbkyrNRk6/EIVIJJLqAWiKQqRU9TSa37tX/j0KFHQP/ X0luzyqvvRBYKXghQ9t1C8cl3GO6n7FDsGg/d4WfS7Bn6m5LAkkXhdLJoVTuLFdbQ9x9 u3UR35xIRCHjzd6uaNLWub2wVxiqdl5H0Sn377FZL/WHsmIAEAC8BUU5pPHuxeS6CaZB YzCSuT1+L+cshmCFpS3/HAvkLpn42XzVXX310JF56Jt+K5vvlcj7YWFG9Rp6BBE7dMRC Ilpg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:user-agent:in-reply-to:content-disposition :mime-version:references:message-id:subject:cc:to:from:date; bh=0av7joUYcUIGeCa6W2KWIsrlXK7ONRvdUaI8Y1BsBQo=; b=zKhx2RGUQ0+m/hyHMtQlj0Q7dlvD/v3ao9uLDuE6lfvKwWLllPwqcSO6BZsuL/FisK hL0eCxROJK4DwhQJRl97aTSIbjkvBMT1SpnLfFtzSeOEg7ajH3ouWO1C+d4V/5DFHOgj 7W69BXONuM3TCrtJJ+DZrOXqOCR73VOro88+3xtEvaHnn7/2D6R6i4NsOq2/TNdhgym1 46HAP7Uu1ffSzjta6ADJccuNBNXNcgu+k+GAW7wn2pectfEcb1950kMO2b1Mi+hrLMMI 1KSHM4Hnjf6ekR7XKzf1jVMU+gtlHpB8Lwttj1b/08+ywfWMsk6D5Vc24XZDgPTVwOQv lHEw== 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 h4si16967696ilj.137.2021.08.09.08.01.58; Mon, 09 Aug 2021 08:02:10 -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 S234421AbhHIPAa (ORCPT + 99 others); Mon, 9 Aug 2021 11:00:30 -0400 Received: from bmailout3.hostsharing.net ([176.9.242.62]:57939 "EHLO bmailout3.hostsharing.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234721AbhHIPA1 (ORCPT ); Mon, 9 Aug 2021 11:00:27 -0400 Received: from h08.hostsharing.net (h08.hostsharing.net [83.223.95.28]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "*.hostsharing.net", Issuer "RapidSSL TLS DV RSA Mixed SHA256 2020 CA-1" (verified OK)) by bmailout3.hostsharing.net (Postfix) with ESMTPS id 56139100D9417; Mon, 9 Aug 2021 17:00:05 +0200 (CEST) Received: by h08.hostsharing.net (Postfix, from userid 100393) id 27B0327FF26; Mon, 9 Aug 2021 17:00:05 +0200 (CEST) Date: Mon, 9 Aug 2021 17:00:05 +0200 From: Lukas Wunner To: Kai-Heng Feng Cc: Bjorn Helgaas , Sean V Kelley , Jonathan Cameron , Qiuxu Zhuo , Kuppuswamy Sathyanarayanan , Keith Busch , "open list:PCI SUBSYSTEM" , open list , Mika Westerberg , "Rafael J. Wysocki" Subject: Re: [PATCH] PCI/portdrv: Disallow runtime suspend when waekup is required but PME service isn't supported Message-ID: <20210809150005.GA6916@wunner.de> References: <20210713075726.1232938-1-kai.heng.feng@canonical.com> <20210809042414.107430-1-kai.heng.feng@canonical.com> <20210809094731.GA16595@wunner.de> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org [cc += Rafael] On Mon, Aug 09, 2021 at 06:40:41PM +0800, Kai-Heng Feng wrote: > On Mon, Aug 9, 2021 at 5:47 PM Lukas Wunner wrote: > > On Mon, Aug 09, 2021 at 12:24:12PM +0800, Kai-Heng Feng wrote: > > > Some platforms cannot detect ethernet hotplug once its upstream port is > > > runtime suspended because PME isn't enabled in _OSC. > > > > If PME is not handled natively, why does the NIC runtime suspend? > > Shouldn't this be fixed in the NIC driver by keeping the device > > runtime active if PME cannot be used? > > That means we need to fix every user of pci_dev_run_wake(), or fix the > issue in pci_dev_run_wake() helper itself. If PME is not granted to the OS, the only consequence is that the PME port service is not instantiated at the root port. But PME is still enabled for downstream devices. Maybe that's a mistake? I think the ACPI spec is a little unclear what to do if PME control is *not* granted. It only specifies what to do if PME control is *granted*: "If the OS successfully receives control of this feature, it must handle power management events as described in the PCI Express Base Specification." "If firmware allows the OS control of this feature, then in the context of the _OSC method it must ensure that all PMEs are routed to root port interrupts as described in the PCI Express Base Specification. Additionally, after control is transferred to the OS, firmware must not update the PME Status field in the Root Status register or the PME Interrupt Enable field in the Root Control register. If control of this feature was requested and denied or was not requested, firmware returns this bit set to 0." Perhaps something like the below is appropriate, I'm not sure. diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 091b4a4..7e64185 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3099,7 +3099,7 @@ void pci_pm_init(struct pci_dev *dev) } pmc &= PCI_PM_CAP_PME_MASK; - if (pmc) { + if (pmc && pci_find_host_bridge(dev->bus)->native_pme) { pci_info(dev, "PME# supported from%s%s%s%s%s\n", (pmc & PCI_PM_CAP_PME_D0) ? " D0" : "", (pmc & PCI_PM_CAP_PME_D1) ? " D1" : "", > > > --- a/drivers/pci/pcie/portdrv_pci.c > > > +++ b/drivers/pci/pcie/portdrv_pci.c > > > @@ -59,14 +59,30 @@ static int pcie_port_runtime_suspend(struct device *dev) > > > return pcie_port_device_runtime_suspend(dev); > > > } > > > > > > +static int pcie_port_wakeup_check(struct device *dev, void *data) > > > +{ > > > + struct pci_dev *pdev = to_pci_dev(dev); > > > + > > > + if (!pdev) > > > + return 0; > > > + > > > + return pdev->wakeup_prepared; > > > +} > > > + > > > static int pcie_port_runtime_idle(struct device *dev) > > > { > > > + struct pci_dev *pdev = to_pci_dev(dev); > > > + > > > + if (!pcie_port_find_device(pdev, PCIE_PORT_SERVICE_PME) && > > > + device_for_each_child(dev, NULL, pcie_port_wakeup_check)) > > > + return -EBUSY; > > > + > > > /* > > > * Assume the PCI core has set bridge_d3 whenever it thinks the port > > > * should be good to go to D3. Everything else, including moving > > > * the port to D3, is handled by the PCI core. > > > */ > > > - return to_pci_dev(dev)->bridge_d3 ? 0 : -EBUSY; > > > + return pdev->bridge_d3 ? 0 : -EBUSY; > > > > If an additional check is necessary for this issue, it should be > > integrated into pci_dev_check_d3cold() instead of pcie_port_runtime_idle(). > > I think PME IRQ and D3cold are different things here. > The root port of the affected NIC doesn't support D3cold because > there's no power resource. If a bridge is runtime suspended to D3, the hierarchy below it is inaccessible, which is basically the same as if it's put in D3cold, hence the name pci_dev_check_d3cold(). That function allows a device to block an upstream bridge from runtime suspending because the device is not allowed to go to D3cold. The function specifically checks whether a device is PME-capable from D3cold. The NIC claims it's capable but the PME event has no effect because PME control wasn't granted to the OS and firmware neglected to set PME Interrupt Enable in the Root Control register. We could check for this case and block runtime PM of bridges based on the rationale that PME polling is needed to detect wakeup. Thanks, Lukas