Re: [PATCH] pci: Allow very large resource windows

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Jun 11, 2014 at 10:23:35AM -0700, Yinghai Lu wrote:
> On Tue, Jun 10, 2014 at 11:01 PM, Guo Chao <yan@xxxxxxxxxxxxxxxxxx> wrote:
> > Well, that's not enough for our 16G BAR ...
> >
> > I thought Yinghai fixed it permanently last time:
> >
> >         http://permalink.gmane.org/gmane.linux.kernel.pci/29142
> >
> > Are you still working on this, Yinghai?
> 
> Hi Guo,
> 
> Please check updated version on your setup.
> 
> Thanks
> 
> Yinghai

> Subject: [PATCH -v3] PCI: Fix bus align checking to support more than 8G
> 
> So add mmio64 mask checking, only allow more than 4G when bridge and all child
> support 64bit res.  Still keep old 2G checking for other path.
> 
> Signed-off-by: Yinghai Lu <yinghai@xxxxxxxxxx>
> 
> ---
>  drivers/pci/setup-bus.c |   40 ++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 38 insertions(+), 2 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
> @@ -928,15 +928,50 @@ 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[14];	/* Alignments from 1Mb to 8Gb */
> +	resource_size_t aligns[44];	/* Alignments from 1Mb to 2^63 */
>  	int order, max_order;
>  	struct resource *b_res = find_free_bus_resource(bus,
>  					mask | IORESOURCE_PREFETCH, type);
>  	resource_size_t children_add_size = 0;
> +	unsigned int mem64_mask;
>  
>  	if (!b_res)
>  		return -ENOSPC;
>  
> +	mem64_mask = b_res->flags & IORESOURCE_MEM_64;
> +
> +	/* kernel does not support 64bit res */
> +	if (sizeof(resource_size_t) == 4)
> +		mem64_mask &= ~IORESOURCE_MEM_64;
> +
> +	if (!mem64_mask)
> +		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];
> +
> +			if (r->parent || ((r->flags & mask) != type &&
> +					  (r->flags & mask) != type2 &&
> +					  (r->flags & mask) != type3))
> +				continue;
> +#ifdef CONFIG_PCI_IOV
> +			/* Skip SRIOV checking, as optional res */
> +			if (realloc_head && i >= PCI_IOV_RESOURCES &&
> +					i <= PCI_IOV_RESOURCE_END)
> +				continue;
> +#endif
> +			mem64_mask &= r->flags & IORESOURCE_MEM_64;
> +
> +			if (!mem64_mask)
> +				goto mem64_mask_check_done;
> +		}
> +	}
> +mem64_mask_check_done:

What happens if we increase the size of aligns[], but omit this loop and
the mem64_mask stuff?  Is mem64_mask just an optimization, so the code
would still work without it?  If the existing code works for 8GB bars
(without mem64_mask), when does it break and start requiring mem64_mask?

>  	memset(aligns, 0, sizeof(aligns));
>  	max_order = 0;
>  	size = 0;
> @@ -973,7 +1008,8 @@ static int pbus_size_mem(struct pci_bus
>  			order = __ffs(align) - 20;
>  			if (order < 0)
>  				order = 0;
> -			if (order >= ARRAY_SIZE(aligns)) {
> +			if (order >= ARRAY_SIZE(aligns) ||
> +			    (!mem64_mask && order > 11 /* 2Gb */)) {
>  				dev_warn(&dev->dev, "disabling BAR %d: %pR "
>  					 "(bad alignment %#llx)\n", i, r,
>  					 (unsigned long long) align);

--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux