From patchwork Thu Dec 25 21:12:47 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Yinghai Lu X-Patchwork-Id: 424066 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 0CB3E14009B for ; Fri, 26 Dec 2014 08:12:57 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751238AbaLYVMt (ORCPT ); Thu, 25 Dec 2014 16:12:49 -0500 Received: from mail-ig0-f178.google.com ([209.85.213.178]:37105 "EHLO mail-ig0-f178.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751000AbaLYVMs (ORCPT ); Thu, 25 Dec 2014 16:12:48 -0500 Received: by mail-ig0-f178.google.com with SMTP id hl2so8263436igb.11 for ; Thu, 25 Dec 2014 13:12:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:date:message-id:subject :from:to:cc:content-type; bh=4LYQeYha3RI6NoSyEBCiXlcYnHoHi36+6DaYKckB758=; b=sxEQoT1Kq3lCu0ELO6EOKIyJWvJfcS+qIenWsMai350g9dJLPsSQXUmsH12AsqU7++ QhoMjQF+OZs4DO6mTWDwF/BDCsEHieNZ2LoqjPitLCDZorW5Jm2oZ85C8jWV1TCwozHI eaG8ajqnrfneE+CohM7tAcb/C7Svmp6wIn0klbRY+XrafXO/a4HT1ahmE4mpr7rYHhg8 1vj55SIa931n3/oW+uOME52ztueJXOPSQgbvTTiyCJT1gf9y5n6k1cM3AtvAUfnhCJSI VMenJ42dWaOCUDqwQQnVzBldSgCwjKwRo5p+bglS0Bxh3Dx7BoFanltYkbcvQDwtZpFY 1r8A== MIME-Version: 1.0 X-Received: by 10.107.17.38 with SMTP id z38mr35829484ioi.29.1419541967705; Thu, 25 Dec 2014 13:12:47 -0800 (PST) Received: by 10.64.123.166 with HTTP; Thu, 25 Dec 2014 13:12:47 -0800 (PST) In-Reply-To: <549C313A.7090504@gmail.com> References: <1418074683.13358.1.camel@kernel.crashing.org> <20141208233855.GA15713@shangw> <20141220002306.GB30834@google.com> <20141223214106.GA27291@google.com> <549C313A.7090504@gmail.com> Date: Thu, 25 Dec 2014 13:12:47 -0800 X-Google-Sender-Auth: rcPYSqO9DYjoIXOxRzcHxw4LBt0 Message-ID: Subject: Re: Regression: bug 85491: radeon 0000:01:00.0: Fatal error during GPU init From: Yinghai Lu To: =?UTF-8?Q?Marek_Kord=C3=ADk?= Cc: Bjorn Helgaas , Gavin Shan , Benjamin Herrenschmidt , "linux-pci@vger.kernel.org" , Alexey Voronkov , David Airlie , Alex Deucher , Richard Yang Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org On Thu, Dec 25, 2014 at 7:46 AM, Marek Kordík wrote: > On 12/24/2014 03:29 AM, Yinghai Lu wrote: > I checked (only) v2 of your patch on versions 3.18.0 and 3.18.1. The result > of both versions is that booting stops with kernel panic. I don't how to get > the full log (there is nothing in journalctl and dmesg after booting some > working kernel - maybe if you can give me some hint what to google) so I > will attach photo of screen to the bugzilla issue. Please check update one. but i still can not understand why do we need if (!r) continue; checking... Subject: [PATCH v3] PCI, x86: clip firmware assigned pci bridges under hostbridge Some bios put range that is not fully coverred by root bus resources. Try to clip them and update them in pci bridge bars. -v2: check with upstream bridge instead of host bridge only. also add debug print out. -v3: fix checking under pci_bus_for_each... Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491 Reported-by: Marek Kordik Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources") Signed-off-by: Yinghai Lu --- arch/x86/pci/i386.c | 81 +++++++++++++++++++++++++++++++++++++--------------- drivers/pci/bus.c | 37 +++++++++++++++++++++++ include/linux/pci.h | 1 3 files changed, 97 insertions(+), 22 deletions(-) Index: linux-2.6/arch/x86/pci/i386.c =================================================================== --- linux-2.6.orig/arch/x86/pci/i386.c +++ linux-2.6/arch/x86/pci/i386.c @@ -205,28 +205,48 @@ EXPORT_SYMBOL(pcibios_align_resource); * as well. */ -static void pcibios_allocate_bridge_resources(struct pci_dev *dev) +static bool pcibios_allocate_bridge_resources(struct pci_dev *dev) { int idx; struct resource *r; + bool changed = false; for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) { + int ret; + r = &dev->resource[idx]; if (!r->flags) continue; if (r->parent) /* Already allocated */ continue; - if (!r->start || pci_claim_resource(dev, idx) < 0) { - /* - * Something is wrong with the region. - * Invalidate the resource to prevent - * child resource allocations in this - * range. - */ - r->start = r->end = 0; - r->flags = 0; + + if (!r->start) + goto clear; + + ret = pci_claim_resource(dev, idx); + if (ret >= 0) + continue; + + /* try again after clip for pci bridge*/ + if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && + pci_bus_clip_resource(dev, r)) { + changed = true; + if (pci_claim_resource(dev, idx) >= 0) + continue; } + +clear: + /* + * Something is wrong with the region. + * Invalidate the resource to prevent + * child resource allocations in this + * range. + */ + r->start = r->end = 0; + r->flags = 0; } + + return changed; } static void pcibios_allocate_bus_resources(struct pci_bus *bus) @@ -234,8 +254,12 @@ static void pcibios_allocate_bus_resourc struct pci_bus *child; /* Depth-First Search on bus tree */ - if (bus->self) - pcibios_allocate_bridge_resources(bus->self); + if (bus->self) { + bool changed = pcibios_allocate_bridge_resources(bus->self); + + if (changed) + pci_setup_bridge(bus); + } list_for_each_entry(child, &bus->children, node) pcibios_allocate_bus_resources(child); } @@ -271,21 +295,34 @@ static void pcibios_allocate_dev_resourc else disabled = !(command & PCI_COMMAND_MEMORY); if (pass == disabled) { + int ret; + dev_dbg(&dev->dev, "BAR %d: reserving %pr (d=%d, p=%d)\n", idx, r, disabled, pass); - if (pci_claim_resource(dev, idx) < 0) { - if (r->flags & IORESOURCE_PCI_FIXED) { - dev_info(&dev->dev, "BAR %d %pR is immovable\n", + + ret = pci_claim_resource(dev, idx); + + if (ret >= 0) + continue; + + if (r->flags & IORESOURCE_PCI_FIXED) { + dev_info(&dev->dev, "BAR %d %pR is immovable\n", idx, r); - } else { - /* We'll assign a new address later */ - pcibios_save_fw_addr(dev, - idx, r->start); - r->end -= r->start; - r->start = 0; - } + continue; + } + + /* try again with clip */ + if (pci_bus_clip_resource(dev, r)) { + pci_update_resource(dev, idx); + if (pci_claim_resource(dev, idx) >= 0) + continue; } + + /* We'll assign a new address later */ + pcibios_save_fw_addr(dev, idx, r->start); + r->end -= r->start; + r->start = 0; } } if (!pass) { Index: linux-2.6/include/linux/pci.h =================================================================== --- linux-2.6.orig/include/linux/pci.h +++ linux-2.6/include/linux/pci.h @@ -1094,6 +1094,7 @@ void pci_free_resource_list(struct list_ void pci_bus_add_resource(struct pci_bus *bus, struct resource *res, unsigned int flags); struct resource *pci_bus_resource_n(const struct pci_bus *bus, int n); void pci_bus_remove_resources(struct pci_bus *bus); +bool pci_bus_clip_resource(struct pci_dev *dev, struct resource *res); #define pci_bus_for_each_resource(bus, res, i) \ for (i = 0; \ Index: linux-2.6/drivers/pci/bus.c =================================================================== --- linux-2.6.orig/drivers/pci/bus.c +++ linux-2.6/drivers/pci/bus.c @@ -228,6 +228,43 @@ int pci_bus_alloc_resource(struct pci_bu } EXPORT_SYMBOL(pci_bus_alloc_resource); +bool pci_bus_clip_resource(struct pci_dev *dev, struct resource *res) +{ + struct pci_bus *bus = dev->bus; + resource_size_t start, end; + struct resource orig_res = *res; + struct resource *r; + int i; + + pci_bus_for_each_resource(bus, r, i) { + if (!r) + continue; + + if (resource_type(res) != resource_type(r)) + continue; + + start = max(r->start, res->start); + end = min(r->end, res->end); + + /* no overlap ? */ + if (start > end) + continue; + + if (res->start == start && res->end == end) + return false; + + /* changed */ + res->start = start; + res->end = end; + dev_printk(KERN_DEBUG, &dev->dev, "%pR ==> %pR\n", + &orig_res, res); + + return true; + } + + return false; +} + void __weak pcibios_resource_survey_bus(struct pci_bus *bus) { } /**