From: Bjorn Helgaas <bhelgaas@google.com>
To: Yinghai Lu <yinghai@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Guo Chao <yan@linux.vnet.ibm.com>,
"linux-pci@vger.kernel.org" <linux-pci@vger.kernel.org>
Subject: Re: [PATCH] pci: Allow very large resource windows
Date: Wed, 3 Sep 2014 22:20:14 -0600 [thread overview]
Message-ID: <20140904042014.GF26073@google.com> (raw)
In-Reply-To: <CAE9FiQXCOvgCTiUhTeBYjHQeMA0wNJ7gJDO9mXXUmZSrH90Exw@mail.gmail.com>
On Fri, Jul 11, 2014 at 06:22:08PM -0700, Yinghai Lu wrote:
> On Fri, Jul 11, 2014 at 11:40 AM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> > On Fri, Jul 11, 2014 at 12:21 PM, Linus Torvalds
> > <torvalds@linux-foundation.org> wrote:
> >> On Fri, Jul 11, 2014 at 11:09 AM, Yinghai Lu <yinghai@kernel.org> wrote:
> >>>
> >>> If the BAR have all 0, cpu can not access it as hw will forward access to ram
> >>> controller according to routing table.
> >>
> >> On PC's, yes (also likely with many devices - there are definitely
> >> devices out there were setting the BAR to zero disables it).
> >
> > Ooh, we might trip over this some day on a platform with host bridge
> > address translation that maps to PCI bus address 0. I don't think we
> > have anything in the allocator that avoids bus address 0 in that case.
>
> Anyway, I draft RFC one that replace flags = 0 with flags |=
> IORESOURCE_UNSET | IORESOURCE_DISABLEd.
I think we should do something like this patch, but we need to clarify how
we want to use the IORESOURCE flags.
Here's what I think these IORESOURCE flags mean:
IORESOURCE_MEM Hardware decodes memory accesses (when enabled)
IORESOURCE_UNSET We have not allocated space for this decoder,
although the hardware still contains some address
IORESOURCE_DISABLED This hardware decoder is disabled, e.g., a bridge
window with LIMIT < BASE, or a ROM BAR with its
enable bit cleared
For PCI, this would imply:
- The resource for a standard BAR should never have IORESOURCE_DISABLED
because it can't be individually disabled.
- We can turn on PCI_COMMAND_MEMORY only if every IORESOURCE_MEM resource
has either (IORESOURCE_DISABLED set) or (IORESOURCE_UNSET cleared).
> Let's see how many drivers will fail.
>
> Yinghai
> Subject: [RFC PATCH] PCI: don't set flags to 0 when assign resource fail
>
> make flags take IORESOURCE_UNSET | IORESOURCE_DISABLE instead.
>
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
>
> ---
> drivers/pci/setup-bus.c | 49 ++++++++++++++++++++++++------------------------
> drivers/pci/setup-res.c | 11 ++++++++++
> 2 files changed, 36 insertions(+), 24 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
> @@ -136,7 +136,8 @@ static void pdev_sort_resources(struct p
> if (r->flags & IORESOURCE_PCI_FIXED)
> continue;
>
> - if (!(r->flags) || r->parent)
> + if (!(r->flags) || r->parent ||
> + (r->flags & IORESOURCE_DISABLED))
> continue;
>
> r_align = pci_resource_alignment(dev, r);
> @@ -190,13 +191,6 @@ static void __dev_sort_resources(struct
> pdev_sort_resources(dev, head);
> }
>
> -static inline void reset_resource(struct resource *res)
> -{
> - res->start = 0;
> - res->end = 0;
> - res->flags = 0;
> -}
> -
> /**
> * reassign_resources_sorted() - satisfy any additional resource requests
> *
> @@ -242,7 +236,7 @@ static void reassign_resources_sorted(st
> res->start = add_res->start;
> res->end = res->start + add_size - 1;
> if (pci_assign_resource(add_res->dev, idx))
> - reset_resource(res);
> + res->flags |= IORESOURCE_DISABLED;
> } else {
> resource_size_t align = add_res->min_align;
> res->flags |= add_res->flags &
> @@ -294,7 +288,7 @@ static void assign_requested_resources_s
> 0 /* don't care */,
> 0 /* don't care */);
> }
> - reset_resource(res);
> + res->flags |= IORESOURCE_DISABLED;
> }
> }
> }
> @@ -547,7 +541,7 @@ static void pci_setup_bridge_io(struct p
> /* Set up the top and bottom of the PCI I/O segment for this bus. */
> res = bus->resource[0];
> pcibios_resource_to_bus(bridge->bus, ®ion, res);
> - if (res->flags & IORESOURCE_IO) {
> + if ((res->flags & IORESOURCE_IO) && !(res->flags & IORESOURCE_UNSET)) {
> pci_read_config_word(bridge, PCI_IO_BASE, &l);
> io_base_lo = (region.start >> 8) & io_mask;
> io_limit_lo = (region.end >> 8) & io_mask;
> @@ -578,7 +572,8 @@ static void pci_setup_bridge_mmio(struct
> /* Set up the top and bottom of the PCI Memory segment for this bus. */
> res = bus->resource[1];
> pcibios_resource_to_bus(bridge->bus, ®ion, res);
> - if (res->flags & IORESOURCE_MEM) {
> + if ((res->flags & IORESOURCE_MEM) &&
> + !(res->flags & IORESOURCE_UNSET)) {
> l = (region.start >> 16) & 0xfff0;
> l |= region.end & 0xfff00000;
> dev_info(&bridge->dev, " bridge window %pR\n", res);
> @@ -604,7 +599,8 @@ static void pci_setup_bridge_mmio_pref(s
> bu = lu = 0;
> res = bus->resource[2];
> pcibios_resource_to_bus(bridge->bus, ®ion, res);
> - if (res->flags & IORESOURCE_PREFETCH) {
> + if ((res->flags & IORESOURCE_PREFETCH) &&
> + !(res->flags & IORESOURCE_UNSET)) {
> l = (region.start >> 16) & 0xfff0;
> l |= region.end & 0xfff00000;
> if (res->flags & IORESOURCE_MEM_64) {
> @@ -661,6 +657,7 @@ static void pci_bridge_check_ranges(stru
>
> b_res = &bridge->resource[PCI_BRIDGE_RESOURCES];
> b_res[1].flags |= IORESOURCE_MEM;
> + b_res[1].flags &= ~IORESOURCE_DISABLED;
>
> pci_read_config_word(bridge, PCI_IO_BASE, &io);
> if (!io) {
> @@ -668,8 +665,10 @@ static void pci_bridge_check_ranges(stru
> pci_read_config_word(bridge, PCI_IO_BASE, &io);
> pci_write_config_word(bridge, PCI_IO_BASE, 0x0);
> }
> - if (io)
> + if (io) {
> b_res[0].flags |= IORESOURCE_IO;
> + b_res[0].flags &= ~IORESOURCE_DISABLED;
> + }
>
> /* DECchip 21050 pass 2 errata: the bridge may miss an address
> disconnect boundary by one PCI data phase.
> @@ -686,6 +685,7 @@ static void pci_bridge_check_ranges(stru
> }
> if (pmem) {
> b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
> + b_res[2].flags &= ~IORESOURCE_DISABLED;
> if ((pmem & PCI_PREF_RANGE_TYPE_MASK) ==
> PCI_PREF_RANGE_TYPE_64) {
> b_res[2].flags |= IORESOURCE_MEM_64;
> @@ -830,8 +830,10 @@ static void pbus_size_io(struct pci_bus
> struct resource *r = &dev->resource[i];
> unsigned long r_size;
>
> - if (r->parent || !(r->flags & IORESOURCE_IO))
> + if (r->parent || !(r->flags & IORESOURCE_IO) ||
> + (r->flags & IORESOURCE_DISABLED))
> continue;
> +
> r_size = resource_size(r);
>
> if (r_size < 0x400)
> @@ -860,7 +862,7 @@ static void pbus_size_io(struct pci_bus
> if (b_res->start || b_res->end)
> dev_info(&bus->self->dev, "disabling bridge window %pR to %pR (unused)\n",
> b_res, &bus->busn_res);
> - b_res->flags = 0;
> + b_res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED;
> return;
> }
>
> @@ -947,8 +949,10 @@ static int pbus_size_mem(struct pci_bus
>
> if (r->parent || ((r->flags & mask) != type &&
> (r->flags & mask) != type2 &&
> - (r->flags & mask) != type3))
> + (r->flags & mask) != type3) ||
> + (r->flags & IORESOURCE_DISABLED))
> continue;
> +
> r_size = resource_size(r);
> #ifdef CONFIG_PCI_IOV
> /* put SRIOV requested res to the optional list */
> @@ -973,7 +977,8 @@ static int pbus_size_mem(struct pci_bus
> if (order >= ARRAY_SIZE(aligns)) {
> dev_warn(&dev->dev, "disabling BAR %d: %pR (bad alignment %#llx)\n",
> i, r, (unsigned long long) align);
> - r->flags = 0;
> + r->flags |= IORESOURCE_UNSET |
> + IORESOURCE_DISABLED;
> continue;
> }
> size += r_size;
> @@ -1001,7 +1006,7 @@ static int pbus_size_mem(struct pci_bus
> if (b_res->start || b_res->end)
> dev_info(&bus->self->dev, "disabling bridge window %pR to %pR (unused)\n",
> b_res, &bus->busn_res);
> - b_res->flags = 0;
> + b_res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED;
> return 0;
> }
> b_res->start = min_align;
> @@ -1367,7 +1372,7 @@ static void pci_bridge_release_resources
> /* keep the old size */
> r->end = resource_size(r) - 1;
> r->start = 0;
> - r->flags = 0;
> + r->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED;
>
> /* avoiding touch the one without PREF */
> if (type & IORESOURCE_PREFETCH)
> @@ -1622,8 +1627,6 @@ again:
> res->start = fail_res->start;
> res->end = fail_res->end;
> res->flags = fail_res->flags;
> - if (fail_res->dev->subordinate)
> - res->flags = 0;
> }
> free_list(&fail_head);
>
> @@ -1688,8 +1691,6 @@ again:
> res->start = fail_res->start;
> res->end = fail_res->end;
> res->flags = fail_res->flags;
> - if (fail_res->dev->subordinate)
> - res->flags = 0;
> }
> free_list(&fail_head);
>
> Index: linux-2.6/drivers/pci/setup-res.c
> ===================================================================
> --- linux-2.6.orig/drivers/pci/setup-res.c
> +++ linux-2.6/drivers/pci/setup-res.c
> @@ -362,6 +362,17 @@ int pci_enable_resources(struct pci_dev
> continue;
>
> if (r->flags & IORESOURCE_UNSET) {
> + /* bridge BAR could be disabled one by one */
> + if (dev->subordinate && i >= PCI_BRIDGE_RESOURCES &&
> + i <= PCI_BRIDGE_RESOURCE_END)
> + continue;
> +
> +#ifdef CONFIG_PCI_IOV
> + /* SRIOV ? */
> + if (i >= PCI_IOV_RESOURCES && i <= PCI_IOV_RESOURCE_END)
> + continue;
> +#endif
> +
> dev_err(&dev->dev, "can't enable device: BAR %d %pR not assigned\n",
> i, r);
> return -EINVAL;
next prev parent reply other threads:[~2014-09-04 4:19 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-06-11 6:01 [PATCH] pci: Allow very large resource windows Guo Chao
2014-06-11 17:23 ` Yinghai Lu
2014-06-12 11:32 ` Guo Chao
2014-07-02 21:07 ` Bjorn Helgaas
2014-07-02 22:54 ` Yinghai Lu
2014-07-03 13:15 ` Bjorn Helgaas
2014-07-03 19:59 ` Yinghai Lu
2014-07-03 22:11 ` Bjorn Helgaas
2014-07-11 1:12 ` Yinghai Lu
2014-07-11 18:00 ` Bjorn Helgaas
2014-07-11 18:09 ` Yinghai Lu
2014-07-11 18:21 ` Linus Torvalds
2014-07-11 18:40 ` Bjorn Helgaas
2014-07-12 1:22 ` Yinghai Lu
2014-09-04 4:20 ` Bjorn Helgaas [this message]
-- strict thread matches above, loose matches on Subject: below --
2014-05-19 13:03 Alan
2014-05-19 20:28 ` Bjorn Helgaas
2014-05-23 17:51 ` Kevin Hilman
2014-05-23 18:41 ` Bjorn Helgaas
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140904042014.GF26073@google.com \
--to=bhelgaas@google.com \
--cc=gregkh@linuxfoundation.org \
--cc=linux-pci@vger.kernel.org \
--cc=torvalds@linux-foundation.org \
--cc=yan@linux.vnet.ibm.com \
--cc=yinghai@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).