[PATCH] PCI: generic: map config window in one go
Ard Biesheuvel
ard.biesheuvel at linaro.org
Fri Jan 29 06:22:24 PST 2016
On 29 January 2016 at 15:19, Ard Biesheuvel <ard.biesheuvel at linaro.org> wrote:
> On 29 January 2016 at 15:17, Ard Biesheuvel <ard.biesheuvel at linaro.org> wrote:
>> Instead of iterating over the PCI config window and performing individual
>> ioremap() calls on all the adjacent slices, perform a single ioremap() to
>> map the entire region, and divvy it up later. This not only prevents
>> leaving some of it mapped if we fail half way through, it also ensures that
>> archs that support huge-vmap can use section mappings to perform the
>> mapping.
>>
>> On my Seattle A0 box, this transforms 128 separate 1 MB mappings that are
>> mapped down to 4 KB pages into a single 128 MB mapping using 2 MB sections,
>> saving 512 KB worth of page tables.
>>
>
> OK, this math is slightly off: 4 KB for each 2 MB section == 64 * 4 == 128 KB
>
Sigh. 64 * 4 == 256 KB
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
>> ---
>>
>> huge-vmap for arm64 proposed here:
>> http://article.gmane.org/gmane.linux.kernel.hardened.devel/1661
>>
>> drivers/pci/host/pci-host-generic.c | 12 +++++++-----
>> 1 file changed, 7 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/pci/host/pci-host-generic.c b/drivers/pci/host/pci-host-generic.c
>> index 1652bc70b145..3251cd779278 100644
>> --- a/drivers/pci/host/pci-host-generic.c
>> +++ b/drivers/pci/host/pci-host-generic.c
>> @@ -161,6 +161,7 @@ static int gen_pci_parse_map_cfg_windows(struct gen_pci *pci)
>> struct device *dev = pci->host.dev.parent;
>> struct device_node *np = dev->of_node;
>> u32 sz = 1 << pci->cfg.ops->bus_shift;
>> + void *window;
>>
>> err = of_address_to_resource(np, 0, &pci->cfg.res);
>> if (err) {
>> @@ -186,14 +187,15 @@ static int gen_pci_parse_map_cfg_windows(struct gen_pci *pci)
>> return -ENOMEM;
>>
>> bus_range = pci->cfg.bus_range;
>> + window = devm_ioremap(dev, pci->cfg.res.start,
>> + (bus_range->end - bus_range->start + 1) * sz);
>> + if (!window)
>> + return -ENOMEM;
>> +
>> for (busn = bus_range->start; busn <= bus_range->end; ++busn) {
>> u32 idx = busn - bus_range->start;
>>
>> - pci->cfg.win[idx] = devm_ioremap(dev,
>> - pci->cfg.res.start + idx * sz,
>> - sz);
>> - if (!pci->cfg.win[idx])
>> - return -ENOMEM;
>> + pci->cfg.win[idx] = window + idx * sz;
>> }
>>
>> return 0;
>> --
>> 2.5.0
>>
More information about the linux-arm-kernel
mailing list