Re: [PATCH 1/4] PCI: refactor io size calculation code

From: Daniel Hellstrom
Date: Mon Apr 11 2011 - 10:56:35 EST


Linus Torvalds wrote:

On Mon, Apr 11, 2011 at 6:18 AM, Daniel Hellstrom <daniel@xxxxxxxxxxx> wrote:


In commit 13583b16592a ("PCI: refactor io size calculation code"):


refactor code that calculates the io size in pbus_size_io()
and pbus_mem_io() into separate functions.

Signed-off-by: Ram Pai <linuxram@xxxxxxxxxx>
---
drivers/pci/setup-bus.c | 66
++++++++++++++++++++++++++++++-----------------
1 files changed, 42 insertions(+), 24 deletions(-)

diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 66cb8f4..2121215 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -404,6 +404,43 @@ static struct resource *find_free_bus_resource(struct
pci_bus *bus, unsigned lon
return NULL;
}



...



+
+static resource_size_t calculate_memsize(resource_size_t size,
+ resource_size_t min_size,
+ resource_size_t size1,
+ resource_size_t old_size,
+ resource_size_t align)
+{
+ if (size < min_size)
+ size = min_size;
+ if (old_size == 1 )
+ old_size = 0;
+ if (size < old_size)
+ size = old_size;
+ size = ALIGN(size + size1, align);
+ return size;
+}
+
/* Sizing the IO windows of the PCI-PCI bridge is trivial,
since these windows have 4K granularity and the IO ranges
of non-bridge PCI devices are limited to 256 bytes.




...



@@ -516,14 +542,6 @@ static int pbus_size_mem(struct pci_bus *bus,
unsigned long mask,
mem64_mask &= r->flags & IORESOURCE_MEM_64;
}
}
- if (size < min_size)
- size = min_size;
- old_size = resource_size(b_res);
- if (old_size == 1)
- old_size = 0;
- if (size < old_size)
- size = old_size;
-
align = 0;
min_align = 0;
for (order = 0; order <= max_order; order++) {
@@ -537,7 +555,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned
long mask,
min_align = align1 >> 1;
align += aligns[order];
}
- size = ALIGN(size, min_align);
+ size = calculate_memsize(size, min_size, 0, resource_size(b_res),
align);



On my SPARC32/LEON4 PCI system I get overlapped areas, double mapped
resources. Some BARs on PCIBUS0 are in the same non-prefetchable memory
range as the secondary bus PCIBUS1. Changing align to min_align in the above
call to calculate_memsize() fixes the problem, and the memory allocation is
the same as with 2.6.36.4 kernel.

I belive this is just a typo.



It does seem that way. The original code used 'min_align' and 'align'
itself is meaningless in that place.


Agree.

Can you confirm that the patch you talk about as fixing things is the attached?

Linus


Yes, the below patch works on the system that triggered the problem before. The last min_align was added in a later patch, I missed it initially.

Thanks,
Daniel

------------------------------------------------------------------------

drivers/pci/setup-bus.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 89d0a6a88df7..ebf51ad1b714 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -676,10 +676,10 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
min_align = align1 >> 1;
align += aligns[order];
}
- size0 = calculate_memsize(size, min_size, 0, resource_size(b_res), align);
+ size0 = calculate_memsize(size, min_size, 0, resource_size(b_res), min_align);
size1 = !add_size ? size :
calculate_memsize(size, min_size+add_size, 0,
- resource_size(b_res), align);
+ resource_size(b_res), min_align);
if (!size0 && !size1) {
if (b_res->start || b_res->end)
dev_info(&bus->self->dev, "disabling bridge window "



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