Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752815AbdHORDf (ORCPT ); Tue, 15 Aug 2017 13:03:35 -0400 Received: from mail.kernel.org ([198.145.29.99]:43868 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752487AbdHORDd (ORCPT ); Tue, 15 Aug 2017 13:03:33 -0400 DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1052E22C8D Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=helgaas@kernel.org Date: Tue, 15 Aug 2017 12:03:31 -0500 From: Bjorn Helgaas To: Ding Tianhong Cc: leedom@chelsio.com, ashok.raj@intel.com, bhelgaas@google.com, werner@chelsio.com, ganeshgr@chelsio.com, asit.k.mallick@intel.com, patrick.j.cramer@intel.com, Suravee.Suthikulpanit@amd.com, Bob.Shaw@amd.com, l.stach@pengutronix.de, amira@mellanox.com, gabriele.paoloni@huawei.com, David.Laight@aculab.com, jeffrey.t.kirsher@intel.com, catalin.marinas@arm.com, will.deacon@arm.com, mark.rutland@arm.com, robin.murphy@arm.com, davem@davemloft.net, alexander.duyck@gmail.com, eric.dumazet@gmail.com, linux-arm-kernel@lists.infradead.org, netdev@vger.kernel.org, linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, linuxarm@huawei.com Subject: Re: [PATCH net RESEND] PCI: fix oops when try to find Root Port for a PCI device Message-ID: <20170815170331.GA4099@bhelgaas-glaptop.roam.corp.google.com> References: <1502810688-12420-1-git-send-email-dingtianhong@huawei.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1502810688-12420-1-git-send-email-dingtianhong@huawei.com> User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3096 Lines: 79 On Tue, Aug 15, 2017 at 11:24:48PM +0800, Ding Tianhong wrote: > Eric report a oops when booting the system after applying > the commit a99b646afa8a ("PCI: Disable PCIe Relaxed..."): > ... > It looks like the pci_find_pcie_root_port() was trying to > find the Root Port for the PCI device which is the Root > Port already, it will return NULL and trigger the problem, > so check the highest_pcie_bridge to fix thie problem. The problem was actually with a Root Complex Integrated Endpoint that has no upstream PCIe device: 00:05.2 System peripheral: Intel Corporation Device 0e2a (rev 04) Subsystem: Intel Corporation Device 0e2a Control: I/O- Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- SERR- Fixes: a99b646afa8a ("PCI: Disable PCIe Relaxed Ordering if unsupported") This also Fixes: c56d4450eb68 ("PCI: Turn off Request Attributes to avoid Chelsio T5 Completion erratum") which added pci_find_pcie_root_port(). Prior to this Relaxed Ordering series, we only used pci_find_pcie_root_port() in a Chelsio quirk that only applied to non-integrated endpoints, so we didn't trip over the bug. > Reported-by: Eric Dumazet > Signed-off-by: Eric Dumazet > Signed-off-by: Ding Tianhong > --- > drivers/pci/pci.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c > index af0cc34..7e2022f 100644 > --- a/drivers/pci/pci.c > +++ b/drivers/pci/pci.c > @@ -522,7 +522,8 @@ struct pci_dev *pci_find_pcie_root_port(struct pci_dev *dev) > bridge = pci_upstream_bridge(bridge); > } > > - if (pci_pcie_type(highest_pcie_bridge) != PCI_EXP_TYPE_ROOT_PORT) > + if (highest_pcie_bridge && > + pci_pcie_type(highest_pcie_bridge) != PCI_EXP_TYPE_ROOT_PORT) > return NULL; > > return highest_pcie_bridge; > -- I think structuring the fix as follows is a little more readable: diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index af0cc3456dc1..587cd7623ed8 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -522,10 +522,11 @@ struct pci_dev *pci_find_pcie_root_port(struct pci_dev *dev) bridge = pci_upstream_bridge(bridge); } - if (pci_pcie_type(highest_pcie_bridge) != PCI_EXP_TYPE_ROOT_PORT) - return NULL; + if (highest_pcie_bridge && + pci_pcie_type(highest_pcie_bridge) == PCI_EXP_TYPE_ROOT_PORT) + return highest_pcie_bridge; - return highest_pcie_bridge; + return NULL; } EXPORT_SYMBOL(pci_find_pcie_root_port);