All of lore.kernel.org
 help / color / mirror / Atom feed
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, &region, 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, &region, 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, &region, 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;


  reply	other threads:[~2014-09-04  4:19 UTC|newest]

Thread overview: 22+ 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 17:51     ` Kevin Hilman
2014-05-23 18:41     ` Bjorn Helgaas
2014-05-23 18:41       ` Bjorn Helgaas
2014-04-28 20:23 Alan

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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.