linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] PCI: rcar: Do not abort on too many inbound dma-ranges
@ 2019-07-09  1:15 marek.vasut
  2019-07-09  1:15 ` [PATCH 2/2] PCI: rcar: Recalculate inbound range alignment for each controller entry marek.vasut
  2019-07-09  6:58 ` [PATCH 1/2] PCI: rcar: Do not abort on too many inbound dma-ranges Geert Uytterhoeven
  0 siblings, 2 replies; 4+ messages in thread
From: marek.vasut @ 2019-07-09  1:15 UTC (permalink / raw)
  To: linux-pci
  Cc: Marek Vasut, Geert Uytterhoeven, Lorenzo Pieralisi, Wolfram Sang,
	linux-renesas-soc

From: Marek Vasut <marek.vasut+renesas@gmail.com>

In case the "dma-ranges" DT property contains either too many ranges
or the range start address is unaligned in such a way that populating
the range into the controller requires multiple entries, a situation
may occur where all ranges cannot be loaded into the controller.

Currently, the driver refuses to probe in such a situation. Relax this
behavior, load as many ranges as possible and warn if some ranges do
not fit anymore.

Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Wolfram Sang <wsa@the-dreams.de>
Cc: linux-renesas-soc@vger.kernel.org
To: linux-pci@vger.kernel.org
---
 drivers/pci/controller/pcie-rcar.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/pcie-rcar.c b/drivers/pci/controller/pcie-rcar.c
index f6a669a9af41..938adff4148f 100644
--- a/drivers/pci/controller/pcie-rcar.c
+++ b/drivers/pci/controller/pcie-rcar.c
@@ -1069,8 +1069,9 @@ static int rcar_pcie_inbound_ranges(struct rcar_pcie *pcie,
 		idx += 2;
 
 		if (idx > MAX_NR_INBOUND_MAPS) {
-			dev_err(pcie->dev, "Failed to map inbound regions!\n");
-			return -EINVAL;
+			dev_warn(pcie->dev,
+				 "Too many inbound regions, not all are mapped.\n");
+			break;
 		}
 	}
 	*index = idx;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] PCI: rcar: Recalculate inbound range alignment for each controller entry
  2019-07-09  1:15 [PATCH 1/2] PCI: rcar: Do not abort on too many inbound dma-ranges marek.vasut
@ 2019-07-09  1:15 ` marek.vasut
  2019-07-10  7:13   ` Simon Horman
  2019-07-09  6:58 ` [PATCH 1/2] PCI: rcar: Do not abort on too many inbound dma-ranges Geert Uytterhoeven
  1 sibling, 1 reply; 4+ messages in thread
From: marek.vasut @ 2019-07-09  1:15 UTC (permalink / raw)
  To: linux-pci
  Cc: Marek Vasut, Geert Uytterhoeven, Lorenzo Pieralisi, Wolfram Sang,
	linux-renesas-soc

From: Marek Vasut <marek.vasut+renesas@gmail.com>

Due to hardware constraints, the size of each inbound range entry
populated into the controller cannot be larger than the alignment
of the entry's start address. Currently, the alignment for each
"dma-ranges" inbound range is calculated only once for each range
and the increment for programming the controller is also derived
from it only once. Thus, a "dma-ranges" entry describing a memory
at 0x48000000 and size 0x38000000 would lead to multiple controller
entries, each 0x08000000 long.

This is inefficient, especially considering that by adding the size
to the start address, the alignment increases. This patch moves the
alignment calculation into the loop populating the controller entries,
thus updating the alignment for each controller entry.

Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Wolfram Sang <wsa@the-dreams.de>
Cc: linux-renesas-soc@vger.kernel.org
To: linux-pci@vger.kernel.org
---
 drivers/pci/controller/pcie-rcar.c | 33 +++++++++++++++---------------
 1 file changed, 17 insertions(+), 16 deletions(-)

diff --git a/drivers/pci/controller/pcie-rcar.c b/drivers/pci/controller/pcie-rcar.c
index 938adff4148f..48f361b5d690 100644
--- a/drivers/pci/controller/pcie-rcar.c
+++ b/drivers/pci/controller/pcie-rcar.c
@@ -1029,25 +1029,26 @@ static int rcar_pcie_inbound_ranges(struct rcar_pcie *pcie,
 	if (restype & IORESOURCE_PREFETCH)
 		flags |= LAM_PREFETCH;
 
-	/*
-	 * If the size of the range is larger than the alignment of the start
-	 * address, we have to use multiple entries to perform the mapping.
-	 */
-	if (cpu_addr > 0) {
-		unsigned long nr_zeros = __ffs64(cpu_addr);
-		u64 alignment = 1ULL << nr_zeros;
+	while (cpu_addr < cpu_end) {
+		/*
+		 * If the size of the range is larger than the alignment of
+		 * the start address, we have to use multiple entries to
+		 * perform the mapping.
+		 */
+		if (cpu_addr > 0) {
+			unsigned long nr_zeros = __ffs64(cpu_addr);
+			u64 alignment = 1ULL << nr_zeros;
 
-		size = min(range->size, alignment);
-	} else {
-		size = range->size;
-	}
-	/* Hardware supports max 4GiB inbound region */
-	size = min(size, 1ULL << 32);
+			size = min(range->size, alignment);
+		} else {
+			size = range->size;
+		}
+		/* Hardware supports max 4GiB inbound region */
+		size = min(size, 1ULL << 32);
 
-	mask = roundup_pow_of_two(size) - 1;
-	mask &= ~0xf;
+		mask = roundup_pow_of_two(size) - 1;
+		mask &= ~0xf;
 
-	while (cpu_addr < cpu_end) {
 		/*
 		 * Set up 64-bit inbound regions as the range parser doesn't
 		 * distinguish between 32 and 64-bit types.
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/2] PCI: rcar: Do not abort on too many inbound dma-ranges
  2019-07-09  1:15 [PATCH 1/2] PCI: rcar: Do not abort on too many inbound dma-ranges marek.vasut
  2019-07-09  1:15 ` [PATCH 2/2] PCI: rcar: Recalculate inbound range alignment for each controller entry marek.vasut
@ 2019-07-09  6:58 ` Geert Uytterhoeven
  1 sibling, 0 replies; 4+ messages in thread
From: Geert Uytterhoeven @ 2019-07-09  6:58 UTC (permalink / raw)
  To: Marek Vasut
  Cc: linux-pci, Marek Vasut, Geert Uytterhoeven, Lorenzo Pieralisi,
	Wolfram Sang, Linux-Renesas

Hi Marek,

On Tue, Jul 9, 2019 at 3:18 AM <marek.vasut@gmail.com> wrote:
> From: Marek Vasut <marek.vasut+renesas@gmail.com>
>
> In case the "dma-ranges" DT property contains either too many ranges
> or the range start address is unaligned in such a way that populating
> the range into the controller requires multiple entries, a situation
> may occur where all ranges cannot be loaded into the controller.
>
> Currently, the driver refuses to probe in such a situation. Relax this
> behavior, load as many ranges as possible and warn if some ranges do
> not fit anymore.
>
> Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com>

Thanks for your patch!

> --- a/drivers/pci/controller/pcie-rcar.c
> +++ b/drivers/pci/controller/pcie-rcar.c
> @@ -1069,8 +1069,9 @@ static int rcar_pcie_inbound_ranges(struct rcar_pcie *pcie,
>                 idx += 2;
>
>                 if (idx > MAX_NR_INBOUND_MAPS) {
> -                       dev_err(pcie->dev, "Failed to map inbound regions!\n");
> -                       return -EINVAL;
> +                       dev_warn(pcie->dev,
> +                                "Too many inbound regions, not all are mapped.\n");
> +                       break;
>                 }
>         }
>         *index = idx;

The incremented idx is stored here.  Hence for each subsequent call to
rcar_pcie_inbound_ranges() from the loop in rcar_pcie_parse_map_dma_ranges(),
it will write to nonexisting registers.

It seems that can already happen now (but only for the last iteration,
just before it errors out), so probably you want to fix that first, by
moving the check to the start of the loop.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 2/2] PCI: rcar: Recalculate inbound range alignment for each controller entry
  2019-07-09  1:15 ` [PATCH 2/2] PCI: rcar: Recalculate inbound range alignment for each controller entry marek.vasut
@ 2019-07-10  7:13   ` Simon Horman
  0 siblings, 0 replies; 4+ messages in thread
From: Simon Horman @ 2019-07-10  7:13 UTC (permalink / raw)
  To: marek.vasut
  Cc: linux-pci, Marek Vasut, Geert Uytterhoeven, Lorenzo Pieralisi,
	Wolfram Sang, linux-renesas-soc

On Tue, Jul 09, 2019 at 03:15:59AM +0200, marek.vasut@gmail.com wrote:
> From: Marek Vasut <marek.vasut+renesas@gmail.com>
> 
> Due to hardware constraints, the size of each inbound range entry
> populated into the controller cannot be larger than the alignment
> of the entry's start address. Currently, the alignment for each
> "dma-ranges" inbound range is calculated only once for each range
> and the increment for programming the controller is also derived
> from it only once. Thus, a "dma-ranges" entry describing a memory
> at 0x48000000 and size 0x38000000 would lead to multiple controller
> entries, each 0x08000000 long.
> 
> This is inefficient, especially considering that by adding the size
> to the start address, the alignment increases. This patch moves the
> alignment calculation into the loop populating the controller entries,
> thus updating the alignment for each controller entry.
> 
> Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com>
> Cc: Geert Uytterhoeven <geert+renesas@glider.be>
> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Wolfram Sang <wsa@the-dreams.de>
> Cc: linux-renesas-soc@vger.kernel.org
> To: linux-pci@vger.kernel.org

Reviewed-by: Simon Horman <horms+renesas@verge.net.au>

> ---
>  drivers/pci/controller/pcie-rcar.c | 33 +++++++++++++++---------------
>  1 file changed, 17 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/pci/controller/pcie-rcar.c b/drivers/pci/controller/pcie-rcar.c
> index 938adff4148f..48f361b5d690 100644
> --- a/drivers/pci/controller/pcie-rcar.c
> +++ b/drivers/pci/controller/pcie-rcar.c
> @@ -1029,25 +1029,26 @@ static int rcar_pcie_inbound_ranges(struct rcar_pcie *pcie,
>  	if (restype & IORESOURCE_PREFETCH)
>  		flags |= LAM_PREFETCH;
>  
> -	/*
> -	 * If the size of the range is larger than the alignment of the start
> -	 * address, we have to use multiple entries to perform the mapping.
> -	 */
> -	if (cpu_addr > 0) {
> -		unsigned long nr_zeros = __ffs64(cpu_addr);
> -		u64 alignment = 1ULL << nr_zeros;
> +	while (cpu_addr < cpu_end) {
> +		/*
> +		 * If the size of the range is larger than the alignment of
> +		 * the start address, we have to use multiple entries to
> +		 * perform the mapping.
> +		 */
> +		if (cpu_addr > 0) {
> +			unsigned long nr_zeros = __ffs64(cpu_addr);
> +			u64 alignment = 1ULL << nr_zeros;
>  
> -		size = min(range->size, alignment);
> -	} else {
> -		size = range->size;
> -	}
> -	/* Hardware supports max 4GiB inbound region */
> -	size = min(size, 1ULL << 32);
> +			size = min(range->size, alignment);
> +		} else {
> +			size = range->size;
> +		}
> +		/* Hardware supports max 4GiB inbound region */
> +		size = min(size, 1ULL << 32);
>  
> -	mask = roundup_pow_of_two(size) - 1;
> -	mask &= ~0xf;
> +		mask = roundup_pow_of_two(size) - 1;
> +		mask &= ~0xf;
>  
> -	while (cpu_addr < cpu_end) {
>  		/*
>  		 * Set up 64-bit inbound regions as the range parser doesn't
>  		 * distinguish between 32 and 64-bit types.
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-07-10  7:14 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-09  1:15 [PATCH 1/2] PCI: rcar: Do not abort on too many inbound dma-ranges marek.vasut
2019-07-09  1:15 ` [PATCH 2/2] PCI: rcar: Recalculate inbound range alignment for each controller entry marek.vasut
2019-07-10  7:13   ` Simon Horman
2019-07-09  6:58 ` [PATCH 1/2] PCI: rcar: Do not abort on too many inbound dma-ranges Geert Uytterhoeven

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).