[PATCH] PCI: generic: map config window in one go
Ard Biesheuvel
ard.biesheuvel at linaro.org
Fri Jan 29 06:19:36 PST 2016
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
> 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