linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
To: Bjorn Helgaas <bhelgaas@google.com>
Cc: Guenter Roeck <linux@roeck-us.net>,
	Yinghai Lu <yinghai@kernel.org>,
	"oe5hpm@gmail.com" <oe5hpm@gmail.com>,
	Ralf Baechle <ralf@linux-mips.org>,
	"James E.J. Bottomley" <jejb@parisc-linux.org>,
	Michael Ellerman <mpe@ellerman.id.au>,
	Richard Henderson <rth@twiddle.net>,
	Benjamin Herrenschmidt <benh@kernel.crashing.org>,
	David Howells <dhowells@redhat.com>,
	Russell King <linux@arm.linux.org.uk>,
	Tony Luck <tony.luck@intel.com>,
	"David S. Miller" <davem@davemloft.net>,
	Ingo Molnar <mingo@redhat.com>, Michal Simek <monstr@monstr.eu>,
	Chris Zankel <chris@zankel.net>,
	"linux-pci@vger.kernel.org" <linux-pci@vger.kernel.org>,
	Ray Jui <rjui@broadcom.com>
Subject: Re: trouble with PCI: Call pci_read_bridge_bases() from core instead of arch code
Date: Wed, 16 Sep 2015 09:58:50 +0100	[thread overview]
Message-ID: <20150916085850.GA17510@red-moon> (raw)
In-Reply-To: <20150915192559.GE25767@google.com>

On Tue, Sep 15, 2015 at 08:25:59PM +0100, Bjorn Helgaas wrote:

[...]

> commit d5da9d99d4d79d877815af96fdbfac829c4ce7b2
> Author: Bjorn Helgaas <bhelgaas@google.com>
> Date:   Tue Sep 15 13:18:04 2015 -0500
> 
>     PCI: Revert "PCI: Call pci_read_bridge_bases() from core instead of arch code"
> 
>     Revert dff22d2054b5 ("PCI: Call pci_read_bridge_bases() from core instead
>     of arch code").
> 
>     Reading PCI bridge windows is not arch-specific in itself, but there is PCI
>     core code that doesn't work correctly if we read them too early.  For
>     example, Hannes found this case on an ARM Freescale i.mx6 board:
> 
>       pci_bus 0000:00: root bus resource [mem 0x01000000-0x01efffff]
>       pci 0000:00:00.0: PCI bridge to [bus 01-ff]
>       pci 0000:00:00.0: BAR 8: no space for [mem size 0x01000000] (mem window)
>       pci 0000:01:00.0: BAR 2: failed to assign [mem size 0x00200000]
>       pci 0000:01:00.0: BAR 1: failed to assign [mem size 0x00004000]
>       pci 0000:01:00.0: BAR 0: failed to assign [mem size 0x00000100]
> 
>     The 00:00.0 mem window needs to be at least 3MB: the 01:00.0 device needs
>     0x204100 of space, and mem windows are megabyte-aligned.
> 
>     Bus sizing can increase a bridge window size, but never *decrease* it (see
>     d65245c3297a ("PCI: don't shrink bridge resources")).  Prior to
>     dff22d2054b5, ARM didn't read bridge windows at all, so the "original size"
>     was zero, and we assigned a 3MB window.
> 
>     After dff22d2054b5, we read the bridge windows before sizing the bus.  The
>     firmware programmed a 16MB window (size 0x01000000) in 00:00.0, and since
>     we never decrease the size, we kept 16MB even though we only needed 3MB.
>     But 16MB doesn't fit in the host bridge aperture, so we failed to assign
>     space for the window and the downstream devices.
> 
>     I think this is a defect in the PCI core: we shouldn't rely on the firmware
>     to assign sensible windows.

I share the same opinion, and I think I will resubmit the same patch we
are reverting again soon, when bridge sizing is sorted :)

Towards that goal, do you think there is a way for us to put together a
branch with all code consolidating resource validation in core PCI code
so that we can test it in all required HW ? What's the best way to do that in
your opinion ? I can set it up for arm and arm64 on my side.

>     Ray reported a similar problem, also on ARM, with Broadcom iProc.
> 
>     Issues like this are too hard to fix right now, so revert dff22d2054b5.
> 
>     Reported-by: Hannes <oe5hpm@gmail.com>
>     Reported-by: Ray Jui <rjui@broadcom.com>
>     Link: http://lkml.kernel.org/r/CAAa04yFQEUJm7Jj1qMT57-LG7ZGtnhNDBe=PpSRa70Mj+XhW-A@mail.gmail.com
>     Link: http://lkml.kernel.org/r/55F75BB8.4070405@broadcom.com
>     Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>

Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>

> diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
> index cded02c..5f387ee 100644
> --- a/arch/alpha/kernel/pci.c
> +++ b/arch/alpha/kernel/pci.c
> @@ -242,7 +242,12 @@ pci_restore_srm_config(void)
> 
>  void pcibios_fixup_bus(struct pci_bus *bus)
>  {
> -       struct pci_dev *dev;
> +       struct pci_dev *dev = bus->self;
> +
> +       if (pci_has_flag(PCI_PROBE_ONLY) && dev &&
> +           (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
> +               pci_read_bridge_bases(bus);
> +       }
> 
>         list_for_each_entry(dev, &bus->devices, bus_list) {
>                 pdev_save_srm_config(dev);
> diff --git a/arch/frv/mb93090-mb00/pci-vdk.c b/arch/frv/mb93090-mb00/pci-vdk.c
> index f9c86c4..f211839 100644
> --- a/arch/frv/mb93090-mb00/pci-vdk.c
> +++ b/arch/frv/mb93090-mb00/pci-vdk.c
> @@ -294,6 +294,8 @@ void pcibios_fixup_bus(struct pci_bus *bus)
>         printk("### PCIBIOS_FIXUP_BUS(%d)\n",bus->number);
>  #endif
> 
> +       pci_read_bridge_bases(bus);
> +
>         if (bus->number == 0) {
>                 struct pci_dev *dev;
>                 list_for_each_entry(dev, &bus->devices, bus_list) {
> diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
> index d89b601..7cc3be9 100644
> --- a/arch/ia64/pci/pci.c
> +++ b/arch/ia64/pci/pci.c
> @@ -533,9 +533,10 @@ void pcibios_fixup_bus(struct pci_bus *b)
>  {
>         struct pci_dev *dev;
> 
> -       if (b->self)
> +       if (b->self) {
> +               pci_read_bridge_bases(b);
>                 pcibios_fixup_bridge_resources(b->self);
> -
> +       }
>         list_for_each_entry(dev, &b->devices, bus_list)
>                 pcibios_fixup_device_resources(dev);
>         platform_pci_fixup_bus(b);
> diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
> index 6b8b752..ae838ed 100644
> --- a/arch/microblaze/pci/pci-common.c
> +++ b/arch/microblaze/pci/pci-common.c
> @@ -863,7 +863,14 @@ void pcibios_setup_bus_devices(struct pci_bus *bus)
> 
>  void pcibios_fixup_bus(struct pci_bus *bus)
>  {
> -       /* Fixup the bus */
> +       /* When called from the generic PCI probe, read PCI<->PCI bridge
> +        * bases. This is -not- called when generating the PCI tree from
> +        * the OF device-tree.
> +        */
> +       if (bus->self != NULL)
> +               pci_read_bridge_bases(bus);
> +
> +       /* Now fixup the bus bus */
>         pcibios_setup_bus_self(bus);
> 
>         /* Now fixup devices on that bus */
> diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
> index c6996cf..b8a0bf5 100644
> --- a/arch/mips/pci/pci.c
> +++ b/arch/mips/pci/pci.c
> @@ -311,6 +311,12 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
> 
>  void pcibios_fixup_bus(struct pci_bus *bus)
>  {
> +       struct pci_dev *dev = bus->self;
> +
> +       if (pci_has_flag(PCI_PROBE_ONLY) && dev &&
> +           (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
> +               pci_read_bridge_bases(bus);
> +       }
>  }
> 
>  EXPORT_SYMBOL(PCIBIOS_MIN_IO);
> diff --git a/arch/mn10300/unit-asb2305/pci.c b/arch/mn10300/unit-asb2305/pci.c
> index deaa893..3dfe2d3 100644
> --- a/arch/mn10300/unit-asb2305/pci.c
> +++ b/arch/mn10300/unit-asb2305/pci.c
> @@ -324,6 +324,7 @@ void pcibios_fixup_bus(struct pci_bus *bus)
>         struct pci_dev *dev;
> 
>         if (bus->self) {
> +               pci_read_bridge_bases(bus);
>                 pcibios_fixup_bridge_resources(bus->self);
>         }
> 
> diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
> index a1d0632..7587b2a 100644
> --- a/arch/powerpc/kernel/pci-common.c
> +++ b/arch/powerpc/kernel/pci-common.c
> @@ -1032,7 +1032,13 @@ void pcibios_set_master(struct pci_dev *dev)
> 
>  void pcibios_fixup_bus(struct pci_bus *bus)
>  {
> -       /* Fixup the bus */
> +       /* When called from the generic PCI probe, read PCI<->PCI bridge
> +        * bases. This is -not- called when generating the PCI tree from
> +        * the OF device-tree.
> +        */
> +       pci_read_bridge_bases(bus);
> +
> +       /* Now fixup the bus bus */
>         pcibios_setup_bus_self(bus);
> 
>         /* Now fixup devices on that bus */
> diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
> index 09d3afc..dc78a4a 100644
> --- a/arch/x86/pci/common.c
> +++ b/arch/x86/pci/common.c
> @@ -166,6 +166,7 @@ void pcibios_fixup_bus(struct pci_bus *b)
>  {
>         struct pci_dev *dev;
> 
> +       pci_read_bridge_bases(b);
>         list_for_each_entry(dev, &b->devices, bus_list)
>                 pcibios_fixup_device_resources(dev);
>  }
> diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c
> index d27b4dc..b848cc3 100644
> --- a/arch/xtensa/kernel/pci.c
> +++ b/arch/xtensa/kernel/pci.c
> @@ -210,6 +210,10 @@ subsys_initcall(pcibios_init);
> 
>  void pcibios_fixup_bus(struct pci_bus *bus)
>  {
> +       if (bus->parent) {
> +               /* This is a subordinate bridge */
> +               pci_read_bridge_bases(bus);
> +       }
>  }
> 
>  void pcibios_set_master(struct pci_dev *dev)
> diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
> index baec33c..a0580af 100644
> --- a/drivers/parisc/dino.c
> +++ b/drivers/parisc/dino.c
> @@ -560,6 +560,9 @@ dino_fixup_bus(struct pci_bus *bus)
>         } else if (bus->parent) {
>                 int i;
> 
> +               pci_read_bridge_bases(bus);
> +
> +
>                 for(i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) {
>                         if((bus->self->resource[i].flags &
>                             (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
> diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
> index 7b9e89b..a32c1f6 100644
> --- a/drivers/parisc/lba_pci.c
> +++ b/drivers/parisc/lba_pci.c
> @@ -693,6 +693,7 @@ lba_fixup_bus(struct pci_bus *bus)
>         if (bus->parent) {
>                 int i;
>                 /* PCI-PCI Bridge */
> +               pci_read_bridge_bases(bus);
>                 for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++)
>                         pci_claim_bridge_resource(bus->self, i);
>         } else {
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index 0b2be17..c8cc0e62 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -855,9 +855,6 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
>                         child->bridge_ctl = bctl;
>                 }
> 
> -               /* Read and initialize bridge resources */
> -               pci_read_bridge_bases(child);
> -
>                 cmax = pci_scan_child_bus(child);
>                 if (cmax > subordinate)
>                         dev_warn(&dev->dev, "bridge has subordinate %02x but max busn %02x\n",
> @@ -918,9 +915,6 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
> 
>                 if (!is_cardbus) {
>                         child->bridge_ctl = bctl;
> -
> -                       /* Read and initialize bridge resources */
> -                       pci_read_bridge_bases(child);
>                         max = pci_scan_child_bus(child);
>                 } else {
>                         /*
> 

  parent reply	other threads:[~2015-09-16  8:58 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-02  9:51 trouble with PCI: Call pci_read_bridge_bases() from core instead of arch code oe5hpm
2015-09-02 17:47 ` Lorenzo Pieralisi
2015-09-02 20:32   ` Bjorn Helgaas
2015-09-03 10:01     ` Lorenzo Pieralisi
2015-09-03 16:21       ` Bjorn Helgaas
2015-09-03 17:57         ` Lorenzo Pieralisi
2015-09-04 14:19         ` Lorenzo Pieralisi
2015-09-04 16:00           ` Yinghai Lu
2015-09-04 16:44             ` Lorenzo Pieralisi
2015-09-04 23:53               ` Yinghai Lu
2015-09-07  9:12                 ` Lorenzo Pieralisi
2015-09-14 10:09                   ` Lorenzo Pieralisi
2015-09-14 16:05                     ` Yinghai Lu
2015-09-14 16:28                       ` Lorenzo Pieralisi
2015-09-14 17:36                         ` Yinghai Lu
2015-09-14 23:58                           ` Yinghai Lu
2015-09-15  9:46                             ` Lorenzo Pieralisi
2015-09-15 15:57                               ` Bjorn Helgaas
2015-09-15 16:30                                 ` Lorenzo Pieralisi
2015-09-15 16:51                                   ` Guenter Roeck
2015-09-15 19:25                                     ` Bjorn Helgaas
2015-09-15 20:26                                       ` Yinghai Lu
2015-09-16  8:58                                       ` Lorenzo Pieralisi [this message]
2015-09-15 20:17                                     ` Yinghai Lu
2015-09-15 21:07                                       ` Guenter Roeck
2015-09-15 21:12                                         ` Yinghai Lu
2015-09-09 11:32                 ` Lorenzo Pieralisi
2015-09-09 16:59                   ` Yinghai Lu
2015-09-09 17:22                     ` Yinghai Lu
2015-09-09 17:38                       ` Lorenzo Pieralisi
2015-09-03 10:03     ` oe5hpm
2015-09-03 10:30       ` oe5hpm
2015-09-03 10:51         ` Lorenzo Pieralisi

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=20150916085850.GA17510@red-moon \
    --to=lorenzo.pieralisi@arm.com \
    --cc=benh@kernel.crashing.org \
    --cc=bhelgaas@google.com \
    --cc=chris@zankel.net \
    --cc=davem@davemloft.net \
    --cc=dhowells@redhat.com \
    --cc=jejb@parisc-linux.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=linux@arm.linux.org.uk \
    --cc=linux@roeck-us.net \
    --cc=mingo@redhat.com \
    --cc=monstr@monstr.eu \
    --cc=mpe@ellerman.id.au \
    --cc=oe5hpm@gmail.com \
    --cc=ralf@linux-mips.org \
    --cc=rjui@broadcom.com \
    --cc=rth@twiddle.net \
    --cc=tony.luck@intel.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).