From patchwork Mon Feb 17 19:28:06 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yinghai Lu X-Patchwork-Id: 321109 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 C79902C00CD for ; Tue, 18 Feb 2014 06:28:09 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754251AbaBQT2I (ORCPT ); Mon, 17 Feb 2014 14:28:08 -0500 Received: from mail-oa0-f52.google.com ([209.85.219.52]:63148 "EHLO mail-oa0-f52.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753060AbaBQT2H (ORCPT ); Mon, 17 Feb 2014 14:28:07 -0500 Received: by mail-oa0-f52.google.com with SMTP id i4so18316047oah.11 for ; Mon, 17 Feb 2014 11:28:06 -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=sxjqtAY3s3K3xomx4dLLTzwcgoNLovOHo6jLCZUdb1Q=; b=08bN9/W6fIHe60cxfRGqy3PUYkNWha2rw+ll9jYr2e5m8OT0DMhl5jOOBs92Sin2+B uMNaMuUwOmwpvaOrFuu1+j/jGsuiuqzug9v8H5BHu7yGYgIudx00fRJJej/O0iRmFghE ZBjCdd/0gwnASOC8hy4AqH10uZB6uuYuzKIlKCVO6ScYGZhK30zdf6Q7CFvXp8utwpkY 06vQg/exX6clVQqCKkjFiO/VujrUq2CfMyZh6j+xAfN3eLc7ZHRzeCHNpqXd8ck13EPI FycqZGwYftM8EEw/6JIBR3ZUlXiumRDJbAljGhvOFokJa24LXQAPGmwyoO8IK2LMTSgF +0GQ== MIME-Version: 1.0 X-Received: by 10.182.176.10 with SMTP id ce10mr22177749obc.31.1392665286203; Mon, 17 Feb 2014 11:28:06 -0800 (PST) Received: by 10.76.153.136 with HTTP; Mon, 17 Feb 2014 11:28:06 -0800 (PST) In-Reply-To: <20140217045004.GB3230@yanx> References: <20140217045004.GB3230@yanx> Date: Mon, 17 Feb 2014 11:28:06 -0800 X-Google-Sender-Auth: a9CXrp4vJv8YvpJTr8P3dN8aBnI Message-ID: Subject: Re: Support huge alignment in pbus_size_mem() From: Yinghai Lu To: Guo Chao Cc: Bjorn Helgaas , "linux-pci@vger.kernel.org" Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org On Sun, Feb 16, 2014 at 8:50 PM, Guo Chao wrote: > pbus_size_mem() limits resource alignment within 2G. We want to extend > this limit to support a 16G BAR. I found similar effort was tried before: > > https://lkml.org/lkml/2012/6/21/411 > > What's the result? Does anyone come up with an adaptive algorithm? I suggest following changes: From: Nikhil P Rao Subject: [PATCH] PCI: Fix bus align checking to support more than 2G current 2G is out of date. -v3: We only need to extend that when 64bit mmio is supported. So extract mmio64 mask checking, and still keep old 2G checking for other path. --- Yinghai Signed-off-by: Yinghai Lu --- drivers/pci/setup-bus.c | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) From: Nikhil P Rao Subject: [PATCH] PCI: Fix bus align checking to support more than 2G current 2G is out of date. -v3: We only need to extend that when 64bit mmio is supported. So extract mmio64 mask checking, and still keep old 2G checking for other path. --- Yinghai Signed-off-by: Yinghai Lu --- drivers/pci/setup-bus.c | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) Index: linux-2.6/drivers/pci/setup-bus.c =================================================================== --- linux-2.6.orig/drivers/pci/setup-bus.c +++ linux-2.6/drivers/pci/setup-bus.c @@ -921,7 +921,7 @@ static int pbus_size_mem(struct pci_bus { struct pci_dev *dev; resource_size_t min_align, align, size, size0, size1; - resource_size_t aligns[12]; /* Alignments from 1Mb to 2Gb */ + resource_size_t aligns[44]; /* Alignments from 1Mb to 2^63 */ int order, max_order; struct resource *b_res = find_free_bus_resource(bus, type); unsigned int mem64_mask = 0; @@ -937,6 +937,40 @@ static int pbus_size_mem(struct pci_bus mem64_mask = b_res->flags & IORESOURCE_MEM_64; b_res->flags &= ~IORESOURCE_MEM_64; + /* kernel does not support 64bit */ + if (sizeof(resource_size_t) == 4) + mem64_mask &= ~IORESOURCE_MEM_64; + + if (!(mem64_mask & IORESOURCE_MEM_64)) + goto mem64_mask_check_done; + + /* check if mem64 support is supported and needed at first */ + list_for_each_entry(dev, &bus->devices, bus_list) { + int i; + + for (i = 0; i < PCI_NUM_RESOURCES; i++) { + struct resource *r = &dev->resource[i]; + resource_size_t r_size; + + if (r->parent || (r->flags & mask) != type) + continue; + r_size = resource_size(r); +#ifdef CONFIG_PCI_IOV + /* put SRIOV requested res to the optional list */ + if (realloc_head && i >= PCI_IOV_RESOURCES && + i <= PCI_IOV_RESOURCE_END) + continue; +#endif + mem64_mask &= r->flags & IORESOURCE_MEM_64; + + if (!(mem64_mask & IORESOURCE_MEM_64)) + goto mem64_mask_check_done; + + } + } + +mem64_mask_check_done: + list_for_each_entry(dev, &bus->devices, bus_list) { int i; @@ -959,8 +993,9 @@ static int pbus_size_mem(struct pci_bus #endif /* For bridges size != alignment */ align = pci_resource_alignment(dev, r); - order = __ffs(align) - 20; - if (order > 11) { + order = __ffs64(align) - 20; + if (order > ARRAY_SIZE(aligns) || + (!(mem64_mask & IORESOURCE_MEM_64) && order > 11) ) { dev_warn(&dev->dev, "disabling BAR %d: %pR " "(bad alignment %#llx)\n", i, r, (unsigned long long) align); @@ -976,7 +1011,6 @@ static int pbus_size_mem(struct pci_bus aligns[order] += align; if (order > max_order) max_order = order; - mem64_mask &= r->flags & IORESOURCE_MEM_64; if (realloc_head) children_add_size += get_res_add_size(realloc_head, r);