PCI: refactor io size calculation code
Quoted 18 lines
refactor code that calculates the io size in
pbus_size_io()andpbus_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(-)drivers/pci/setup-bus.c +0
-0@@ -404,6 +404,43 @@ static struct resource *find_free_bus_resource(struct pci_bus *bus, unsigned lonreturn NULL ; }
...
Quoted 23 lines
drivers/pci/setup-bus.c +17
-0+ +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.
...
Quoted 16 lines
drivers/pci/setup-bus.c +0
-8@@ -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++) {
drivers/pci/setup-bus.c static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, · line 560
Quoted 7 lines
drivers/pci/setup-bus.c +1
-1@@ -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.
Best Regards,
Daniel Hellstrom
Aeroflex Gaisler
Quoted 6 lines
drivers/pci/setup-bus.c +0
-0if (!size) {if (b_res->start || b_res->end) dev_info(&bus->self->dev, "disabling bridge window "Signature · 1 line
1.6.5.2
Quoted 79 lines · Daniel Hellstrom
In commit
13583b16592a("PCI: refactor io size calculation code"):Quoted 19 lines
refactor code that calculates the io size in
pbus_size_io()andpbus_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(-)drivers/pci/setup-bus.c +0
-0@@ -404,6 +404,43 @@ static struct resource *find_free_bus_resource(struct
pci_bus*bus, unsigned lon
return NULL;
}...
Quoted 22 lines
drivers/pci/setup-bus.c +17
-0+ +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.
...
Quoted 17 lines
drivers/pci/setup-bus.c +0
-8@@ -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++) {drivers/pci/setup-bus.c static int pbus_size_mem(struct pci_bus *bus, unsigned · line 561
Quoted 8 lines
drivers/pci/setup-bus.c +1
-1@@ -537,7 +555,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsignedlong 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_alignin the above call tocalculate_memsize()fixes the problem, and the memory allocation is the same as with 2.6.36.4 kernel.
Quoted 1 line
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.
Can you confirm that the patch you talk about as fixing things is the attached?
Linus
drivers/pci/setup-bus.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
drivers/pci/setup-bus.c +2 -2
@@ -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 "
Quoted 91 lines · Linus Torvalds
Quoted 88 lines · Daniel Hellstrom
In commit
13583b16592a("PCI: refactor io size calculation code"):Quoted 20 lines
refactor code that calculates the io size in
pbus_size_io()andpbus_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(-)drivers/pci/setup-bus.c +0
-0@@ -404,6 +404,43 @@ static struct resource *find_free_bus_resource(struct
pci_bus*bus, unsigned lonreturn NULL; }...
Quoted 24 lines
drivers/pci/setup-bus.c +17
-0+ +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....
Quoted 19 lines
drivers/pci/setup-bus.c +0
-8@@ -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++) {drivers/pci/setup-bus.c static int pbus_size_mem(struct pci_bus *bus, unsigned · line 561
Quoted 8 lines
drivers/pci/setup-bus.c +1
-1@@ -537,7 +555,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsignedlong 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_alignin the above call tocalculate_memsize()fixes the problem, and the memory allocation is the same as with 2.6.36.4 kernel.
Quoted 8 lines
Quoted 3 lines
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.
Quoted 5 lines
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
Quoted 24 lines
------------------------------------------------------------------------
drivers/pci/setup-bus.c| 4 ++--1 files changed, 2 insertions(+), 2 deletions(-)drivers/pci/setup-bus.c +2
-2@@ -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 "
Quoted 80 lines · Linus Torvalds
Quoted 79 lines · Daniel Hellstrom
In commit
13583b16592a("PCI: refactor io size calculation code"):Quoted 19 lines
refactor code that calculates the io size in
pbus_size_io()andpbus_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(-)drivers/pci/setup-bus.c +0
-0@@ -404,6 +404,43 @@ static struct resource *find_free_bus_resource(struct
pci_bus*bus, unsigned lon
return NULL;
}...
Quoted 22 lines
drivers/pci/setup-bus.c +17
-0+ +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.
...
Quoted 17 lines
drivers/pci/setup-bus.c +0
-8@@ -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++) {drivers/pci/setup-bus.c static int pbus_size_mem(struct pci_bus *bus, unsigned · line 561
Quoted 8 lines
drivers/pci/setup-bus.c +1
-1@@ -537,7 +555,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsignedlong 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_alignin the above call tocalculate_memsize()fixes the problem, and the memory allocation is the same as with 2.6.36.4 kernel.
Quoted 1 line
Quoted 1 line
I belive this is just a typo.
Yes it is my mistake. I got the parameter wrong. Your fix should correct the problem.
RP