From patchwork Thu Oct 25 09:02:32 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Yijing Wang X-Patchwork-Id: 194078 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 9D01A2C00A4 for ; Thu, 25 Oct 2012 20:03:34 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934968Ab2JYJDa (ORCPT ); Thu, 25 Oct 2012 05:03:30 -0400 Received: from szxga02-in.huawei.com ([119.145.14.65]:17430 "EHLO szxga02-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934647Ab2JYJD0 (ORCPT ); Thu, 25 Oct 2012 05:03:26 -0400 Received: from 172.24.2.119 (EHLO szxeml205-edg.china.huawei.com) ([172.24.2.119]) by szxrg02-dlp.huawei.com (MOS 4.3.4-GA FastPath queued) with ESMTP id ARD67116; Thu, 25 Oct 2012 17:03:14 +0800 (CST) Received: from SZXEML402-HUB.china.huawei.com (10.82.67.32) by szxeml205-edg.china.huawei.com (172.24.2.58) with Microsoft SMTP Server (TLS) id 14.1.323.3; Thu, 25 Oct 2012 17:02:38 +0800 Received: from [127.0.0.1] (10.135.76.84) by szxeml402-hub.china.huawei.com (10.82.67.32) with Microsoft SMTP Server id 14.1.323.3; Thu, 25 Oct 2012 17:02:36 +0800 Message-ID: <50890028.8040604@huawei.com> Date: Thu, 25 Oct 2012 17:02:32 +0800 From: Yijing Wang User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:16.0) Gecko/20121010 Thunderbird/16.0.1 MIME-Version: 1.0 To: Jon Mason CC: Bjorn Helgaas , Subject: Re: [PATCH 3/3] PCI: Add new default PCI-E MPS bus state References: <1350020155-3782-1-git-send-email-jdmason@kudzu.us> <1350020155-3782-4-git-send-email-jdmason@kudzu.us> <507B75D6.201@huawei.com> In-Reply-To: X-Originating-IP: [10.135.76.84] X-CFilter-Loop: Reflected Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Hi Jon, I think we can do a little more about inconsistent mps problem found in boot path(BIOS configure bug for mps) or after hotplug device.As shown in your comment on line 1451, it's unsafe to modifying the MPS on the running devices. Since bus child devices is not running when pcie_bus_configure_settings be called. So we can try to configure child device's mps according to the mps of bus. there are two situations: 1、now current running bus mps is larger than child devices mpss can support; 2、now cuurent running bus mps is smaller than child devices mpss can support; We cannot modifying the MPS for 1, it's not safe; but we can show message to user to add boot parameter pci=pcie_bus_safe. The second situation we can modify all child devices mps as the mps value of running bus, it's safe and can correct mps problem automatically for users. I wrote a draft patch about this solution, if there is some thing wrong with my understanding, let me know. Thanks very much! Yijing diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 5485883..59036a8 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -78,7 +78,7 @@ unsigned long pci_cardbus_mem_size = DEFAULT_CARDBUS_MEM_SIZE; unsigned long pci_hotplug_io_size = DEFAULT_HOTPLUG_IO_SIZE; unsigned long pci_hotplug_mem_size = DEFAULT_HOTPLUG_MEM_SIZE; -enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_TUNE_OFF; +enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_AUTO; /* * The default CLS is used if arch didn't set CLS explicitly and not diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index e8b7d5e..6cbfbe1 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1467,6 +1467,19 @@ static int pcie_find_smpss(struct pci_dev *dev, void *data) return 0; } +static int pcie_find_min_mpss(struct pci_dev *dev, void *data) +{ + u8 *mpss = data; + + if (!pci_is_pcie(dev)) + return 0; + + if (*mpss > dev->pcie_mpss) + *mpss = dev->pcie_mpss; + + return 0; +} + static void pcie_write_mps(struct pci_dev *dev, int mps) { int rc; @@ -1560,6 +1573,7 @@ static int pcie_bus_configure_set(struct pci_dev *dev, void *data) void pcie_bus_configure_settings(struct pci_bus *bus, u8 mpss) { u8 smpss; + u8 mps = pcie_get_mps(bus->self) >> 8; if (!pci_is_pcie(bus->self)) return; @@ -1581,7 +1595,19 @@ void pcie_bus_configure_settings(struct pci_bus *bus, u8 mpss) case PCIE_BUS_PEER2PEER: smpss = 0; break; - + case PCIE_BUS_AUTO: + smpss = bus->self->pcie_mpss; + pci_walk_bus(bus, pcie_find_min_mpss, &smpss); + if (mps > smpss) { + dev_info(&bus->dev, + "Current mps %d used in bus 0x%02x is larger than children devices mpss %d support\n" + "Please use the pci=pcie_bus_safe boot parameter for safe\n", + 128 << mpss, bus->number, 128 << smpss); + return; + } + else + pci_walk_bus(bus, pcie_bus_configure_set, &mps); + return; case PCIE_BUS_SAFE: smpss = mpss; @@ -1594,8 +1620,6 @@ void pcie_bus_configure_settings(struct pci_bus *bus, u8 mpss) return; } - } - pcie_bus_configure_set(bus->self, &smpss); pci_walk_bus(bus, pcie_bus_configure_set, &smpss); } diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 7a451ff..539b7e4 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2787,7 +2787,8 @@ static void __devinit quirk_intel_mc_errata(struct pci_dev *dev) int err; u16 rcc; - if (pcie_bus_config == PCIE_BUS_TUNE_OFF) + if (pcie_bus_config == PCIE_BUS_TUNE_OFF || + pcie_bus_config == PCIE_AUTO_AUTO) return; /* Intel errata specifies bits to change but does not say what they are. diff --git a/include/linux/pci.h b/include/linux/pci.h index be1de01..84c4ab1 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -661,6 +661,7 @@ extern void pcie_bus_configure_settings(struct pci_bus *bus, u8 smpss); enum pcie_bus_config_types { PCIE_BUS_TUNE_OFF, + PCIE_BUS_AUTO, PCIE_BUS_SAFE, PCIE_BUS_PERFORMANCE, PCIE_BUS_PEER2PEER,