Received: by 2002:a05:6a10:1287:0:0:0:0 with SMTP id d7csp3893501pxv; Mon, 26 Jul 2021 15:04:53 -0700 (PDT) X-Google-Smtp-Source: ABdhPJx8vdXycOYeuz40hdsoe29UB5/kjg64gpF6eUj6kKe2HoRuMsazGFXw1XX0AeOUjRBogmN4 X-Received: by 2002:a6b:14ca:: with SMTP id 193mr16606036iou.206.1627337093181; Mon, 26 Jul 2021 15:04:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1627337093; cv=none; d=google.com; s=arc-20160816; b=0uBDABJxifzdfV26+axz96e/eIW/5pYal2sRHu6YZ3eJA5xvxgZCK15cOc+Vwvftjq zisJ0aJWJwroL5RGpwEWGwa49BB+G12kVE67LGOTQ/0iXdeA+IT1IpidCdSWxlCC1ehu HvV90dn0XRNHrYkhqZZWFuESqrFPzfvLTdrJL1K0tZ/tHVS6YFigaUQGJC4tY4bX4kC0 gXqHlARuJaxcBk3NKdxPP2FdIJXknGERzBzRnL8aKfVQcoEv1tc/g5DSf97EPzolHMjn fJc2Eh6pBs6amhChc6YtAEGNLFdAFMzAueiQVZtbzXQAOL0MeTMwOrtTzxmnOjogV7y2 JTMg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-disposition:mime-version :message-id:subject:cc:to:from:date:dkim-signature; bh=n+2HvuSaVN3wfK4jlbZqitxi3NzwGNwuajjGTrvsRJs=; b=gyIde1wbjVSP79aYyvJvnSoQtLnaKOUlacfTIxNCjyF0eFZKfDWSmfLAWzVe/LGG6v AFNukBrFNJujz7AjrpR//UqyjDj7pmfOafxI2n0V7WKGHayllyIhwG3TsWPPp30ktwS8 pEmAl/9fQy7Wt2bSSeDOcgi1mKvdMfq8+S/GTKvRcjUpC4U+e58LsTeT24JZq49PN2hs Df0144/Oxmx69O5f05voZQqOCrr5urxoy/5xMA+68mKzscZeEp1hHuXARHR2R4LazkiU qAdcc89CUJO1ojXg1X19OcCBsrOxtjawDsozIw+tsgZf/8xaYFu4rjBCZYmxAKTkmTJF kaDg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="nnA/ezjP"; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id g6si1258013ilf.57.2021.07.26.15.04.38; Mon, 26 Jul 2021 15:04:53 -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; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="nnA/ezjP"; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232876AbhGZVWo (ORCPT + 99 others); Mon, 26 Jul 2021 17:22:44 -0400 Received: from mail.kernel.org ([198.145.29.99]:51460 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231839AbhGZVWn (ORCPT ); Mon, 26 Jul 2021 17:22:43 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id AC6A060F37; Mon, 26 Jul 2021 22:03:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1627336992; bh=gZEtpD5ttAyQ52+nu82eAAbPdSUGMQ3iJJ5aYY960/c=; h=Date:From:To:Cc:Subject:In-Reply-To:From; b=nnA/ezjPAOKv/UFOUMRwSMO3qufjx5+Wf9fN1clFcgLZb99yefbdce1x9WrUW79hS 48h1JibMF3fLPRR5e6zNxofoL6UWUgIT3RSaUw8Aq8fTyFV1q8gmWBnJL3s2jDGS29 oC/99jumoxT4n13QAEAM4pJmPvICFteMjEUnnQ2SCExpT1liu6NmtYvyB/ckeTA/wb g5Xx2mASwoUR+YFu4TUMUsGhNKc/2ghEo8myS+FxNK//GTAo0X00SALHRrTljDPt5z ip7RD4OLnjRitFtqnTwhjlf9dB6cZQyR7l2SBdIBbO1W2NBfbGa+UbQkyKFdkcf5wG hSdUm+xbfG46Q== Date: Mon, 26 Jul 2021 17:03:07 -0500 From: Bjorn Helgaas To: Victor Ding Cc: Ulf Hansson , Adrian Hunter , Ben Chuang , linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mmc@vger.kernel.org, Bjorn Helgaas , Chris Packham , Kai-Heng Feng , Mika Westerberg , "Saheed O. Bolarinwa" , Vidya Sagar , Xiongfeng Wang Subject: Re: [PATCH v2] PCI/ASPM: Disable ASPM when save/restore PCI state Message-ID: <20210726220307.GA647936@bjorn-Precision-5520> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20210311173433.GA2071075@bjorn-Precision-5520> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Mar 11, 2021 at 11:34:33AM -0600, Bjorn Helgaas wrote: > On Thu, Jan 28, 2021 at 03:52:42PM +0000, Victor Ding wrote: > > Certain PCIe devices (e.g. GL9750) have high penalties (e.g. high Port > > T_POWER_ON) when exiting L1 but enter L1 aggressively. As a result, > > such devices enter and exit L1 frequently during pci_save_state and > > pci_restore_state; eventually causing poor suspend/resume performance. > > > > Based on the observation that PCI accesses dominance pci_save_state/ > > pci_restore_state plus these accesses are fairly close to each other, the > > actual time the device could stay in low power states is negligible. > > Therefore, the little power-saving benefit from ASPM during suspend/resume > > does not overweight the performance degradation caused by high L1 exit > > penalties. > > > > Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=211187 > > Thanks for this! > > This device can tolerate unlimited delay for L1 exit (DevCtl Endpoint > L1 Acceptable Latency is unlimited) and it makes no guarantees about > how fast it can exit L1 (LnkCap L1 Exit Latency is also unlimited), so > I think there's basically no restriction on when it can enter ASPM > L1.0. > > I have a hard time interpreting the L1.2 entry conditions in PCIe > r5.0, sec 5.5.1, but I can believe it enters L1.2 aggressively since > the device says it can tolerate any latencies. > > If L1.2 exit takes 3100us, it could do ~60 L1 exits in 200ms. I guess > config accesses and code execution can account for some of that, but > still seems like a lot of L1 entries/exits during suspend. I wouldn't > think we would touch the device that much and that intermittently. > > > Signed-off-by: Victor Ding > > > > --- > > > > Changes in v2: > > - Updated commit message to remove unnecessary information > > - Fixed a bug reading wrong register in pcie_save_aspm_control > > - Updated to reuse existing pcie_config_aspm_dev where possible > > - Fixed goto label style > > > > drivers/pci/pci.c | 18 +++++++++++++++--- > > drivers/pci/pci.h | 6 ++++++ > > drivers/pci/pcie/aspm.c | 27 +++++++++++++++++++++++++++ > > include/linux/pci.h | 1 + > > 4 files changed, 49 insertions(+), 3 deletions(-) > > > > diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c > > index 32011b7b4c04..9ea88953f90b 100644 > > --- a/drivers/pci/pci.c > > +++ b/drivers/pci/pci.c > > @@ -1542,6 +1542,10 @@ static void pci_restore_ltr_state(struct pci_dev *dev) > > int pci_save_state(struct pci_dev *dev) > > { > > int i; > > + > > + pcie_save_aspm_control(dev); > > + pcie_disable_aspm(dev); > > If I understand this patch correctly, it basically does this: > > pci_save_state > + pcie_save_aspm_control > + pcie_disable_aspm > > + pcie_restore_aspm_control > > The part is just a bunch of config reads with very little > other code execution. I'm really surprised that there's enough time > between config reads for the link to go to L1. I guess you've > verified that this does speed up suspend significantly, but this just > doesn't make sense to me. > > In the bugzilla you say the GL9750 can go to L1.2 after ~4us of > inactivity. That's enough time for a lot of code execution. We must > be missing something. There's so much PCI traffic during save/restore > that it should be easy to match up the analyzer trace with the code. > Can you get any insight into what's going on that way? I'm dropping this for now, pending a better understanding of what's going on. > > /* XXX: 100% dword access ok here? */ > > for (i = 0; i < 16; i++) { > > pci_read_config_dword(dev, i * 4, &dev->saved_config_space[i]); > > @@ -1552,18 +1556,22 @@ int pci_save_state(struct pci_dev *dev) > > > > i = pci_save_pcie_state(dev); > > if (i != 0) > > - return i; > > + goto exit; > > > > i = pci_save_pcix_state(dev); > > if (i != 0) > > - return i; > > + goto exit; > > > > pci_save_ltr_state(dev); > > pci_save_aspm_l1ss_state(dev); > > pci_save_dpc_state(dev); > > pci_save_aer_state(dev); > > pci_save_ptm_state(dev); > > - return pci_save_vc_state(dev); > > + i = pci_save_vc_state(dev); > > + > > +exit: > > + pcie_restore_aspm_control(dev); > > + return i; > > } > > EXPORT_SYMBOL(pci_save_state); > > > > @@ -1661,6 +1669,8 @@ void pci_restore_state(struct pci_dev *dev) > > if (!dev->state_saved) > > return; > > > > + pcie_disable_aspm(dev); > > + > > /* > > * Restore max latencies (in the LTR capability) before enabling > > * LTR itself (in the PCIe capability). > > @@ -1689,6 +1699,8 @@ void pci_restore_state(struct pci_dev *dev) > > pci_enable_acs(dev); > > pci_restore_iov_state(dev); > > > > + pcie_restore_aspm_control(dev); > > + > > dev->state_saved = false; > > } > > EXPORT_SYMBOL(pci_restore_state); > > diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h > > index a81459159f6d..e074a0cbe73c 100644 > > --- a/drivers/pci/pci.h > > +++ b/drivers/pci/pci.h > > @@ -584,6 +584,9 @@ void pcie_aspm_pm_state_change(struct pci_dev *pdev); > > void pcie_aspm_powersave_config_link(struct pci_dev *pdev); > > void pci_save_aspm_l1ss_state(struct pci_dev *dev); > > void pci_restore_aspm_l1ss_state(struct pci_dev *dev); > > +void pcie_save_aspm_control(struct pci_dev *dev); > > +void pcie_restore_aspm_control(struct pci_dev *dev); > > +void pcie_disable_aspm(struct pci_dev *pdev); > > #else > > static inline void pcie_aspm_init_link_state(struct pci_dev *pdev) { } > > static inline void pcie_aspm_exit_link_state(struct pci_dev *pdev) { } > > @@ -591,6 +594,9 @@ static inline void pcie_aspm_pm_state_change(struct pci_dev *pdev) { } > > static inline void pcie_aspm_powersave_config_link(struct pci_dev *pdev) { } > > static inline void pci_save_aspm_l1ss_state(struct pci_dev *dev) { } > > static inline void pci_restore_aspm_l1ss_state(struct pci_dev *dev) { } > > +static inline void pcie_save_aspm_control(struct pci_dev *dev) { } > > +static inline void pcie_restore_aspm_control(struct pci_dev *dev) { } > > +static inline void pcie_disable_aspm(struct pci_dev *pdev) { } > > #endif > > > > #ifdef CONFIG_PCIE_ECRC > > diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c > > index a08e7d6dc248..e1e97db32e8b 100644 > > --- a/drivers/pci/pcie/aspm.c > > +++ b/drivers/pci/pcie/aspm.c > > @@ -784,6 +784,33 @@ static void pcie_config_aspm_dev(struct pci_dev *pdev, u32 val) > > PCI_EXP_LNKCTL_ASPMC, val); > > } > > > > +void pcie_disable_aspm(struct pci_dev *pdev) > > +{ > > + if (!pci_is_pcie(pdev)) > > + return; > > + > > + pcie_config_aspm_dev(pdev, 0); > > +} > > + > > +void pcie_save_aspm_control(struct pci_dev *pdev) > > +{ > > + u16 lnkctl; > > + > > + if (!pci_is_pcie(pdev)) > > + return; > > + > > + pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &lnkctl); > > + pdev->saved_aspm_ctl = lnkctl & PCI_EXP_LNKCTL_ASPMC; > > +} > > + > > +void pcie_restore_aspm_control(struct pci_dev *pdev) > > +{ > > + if (!pci_is_pcie(pdev)) > > + return; > > + > > + pcie_config_aspm_dev(pdev, pdev->saved_aspm_ctl); > > +} > > + > > static void pcie_config_aspm_link(struct pcie_link_state *link, u32 state) > > { > > u32 upstream = 0, dwstream = 0; > > diff --git a/include/linux/pci.h b/include/linux/pci.h > > index b32126d26997..a21bfd6e3f89 100644 > > --- a/include/linux/pci.h > > +++ b/include/linux/pci.h > > @@ -387,6 +387,7 @@ struct pci_dev { > > unsigned int ltr_path:1; /* Latency Tolerance Reporting > > supported from root to here */ > > u16 l1ss; /* L1SS Capability pointer */ > > + u16 saved_aspm_ctl; /* ASPM Control saved at suspend time */ > > #endif > > unsigned int eetlp_prefix_path:1; /* End-to-End TLP Prefix */ > > > > -- > > 2.30.0.280.ga3ce27912f-goog > >