linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] Fix Random Kernel panic from when fail to reserve memory
@ 2023-04-06 15:14 Lucas Tanure
  2023-04-06 15:14 ` [PATCH 1/2] memblock: Differentiate regions overlap from both regions being the same Lucas Tanure
  2023-04-06 15:14 ` [PATCH 2/2] of: fdt: Allow the kernel to mark nomap regions received from fdt Lucas Tanure
  0 siblings, 2 replies; 5+ messages in thread
From: Lucas Tanure @ 2023-04-06 15:14 UTC (permalink / raw)
  To: Rob Herring, Frank Rowand, Mike Rapoport, Andrew Morton
  Cc: devicetree, linux-kernel, linux-mm, jbrunet, linux-amlogic,
	linux-arm-kernel, martin.blumenstingl, narmstrong, stefan,
	Lucas Tanure

I am trying to fix an issue where the kernel panics randomly on my Vim3 board.
The issue happens when the ARM Trusted Firmware memory is not removed from the
available ram.

This happens because my u-boot provides this region as a /memreserve/, but it
doesn't flag it as nomap. And the kernel can't map as nomap as the region is
already reserved.
My proposal here is to allow the kernel to mark as nomap if the region from
the device tree and FDT have the same base and size.

arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi:
	/* 3 MiB reserved for ARM Trusted Firmware (BL31) */
	secmon_reserved: secmon@5000000 {
		reg = <0x0 0x05000000 0x0 0x300000>;
		no-map;
	};

Previos Threads:
#regzbot link: https://lore.kernel.org/linux-arm-kernel/40ca11f84b7cdbfb9ad2ddd480cb204a@agner.ch/#regzbot
#regzbot link: https://lore.kernel.org/all/CAJX_Q+1Tjc+-TjZ6JW9X0NxEdFe=82a9626yL63j7uVD4LpxEA@mail.gmail.com/

Lucas Tanure (2):
  memblock: Differentiate regions overlap from both regions being the
    same
  of: fdt: Allow the kernel to mark nomap regions received from fdt

 drivers/of/fdt.c         | 10 ++++++----
 include/linux/memblock.h | 18 +++++++++++++++---
 mm/memblock.c            | 37 ++++++++++++++++++++++++-------------
 3 files changed, 45 insertions(+), 20 deletions(-)

-- 
2.40.0



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

* [PATCH 1/2] memblock: Differentiate regions overlap from both regions being the same
  2023-04-06 15:14 [PATCH 0/2] Fix Random Kernel panic from when fail to reserve memory Lucas Tanure
@ 2023-04-06 15:14 ` Lucas Tanure
  2023-04-06 15:14 ` [PATCH 2/2] of: fdt: Allow the kernel to mark nomap regions received from fdt Lucas Tanure
  1 sibling, 0 replies; 5+ messages in thread
From: Lucas Tanure @ 2023-04-06 15:14 UTC (permalink / raw)
  To: Rob Herring, Frank Rowand, Mike Rapoport, Andrew Morton
  Cc: devicetree, linux-kernel, linux-mm, jbrunet, linux-amlogic,
	linux-arm-kernel, martin.blumenstingl, narmstrong, stefan,
	Lucas Tanure

Add support for memblock_addrs_overlap to return a different value when
both regions are exactly the same region, where base and size are equal
between the regions.

Signed-off-by: Lucas Tanure <tanure@linux.com>
---
 include/linux/memblock.h | 18 +++++++++++++++---
 mm/memblock.c            | 37 ++++++++++++++++++++++++-------------
 2 files changed, 39 insertions(+), 16 deletions(-)

diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index 50ad19662a32..c7ba8b01a637 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -49,6 +49,18 @@ enum memblock_flags {
 	MEMBLOCK_DRIVER_MANAGED = 0x8,	/* always detected via a driver */
 };
 
+/**
+ * enum memblock_overlap_type - result of comparison between two memory regions
+ * @MEMBLOCK_NO_OVERLAPS: there is no overlap between the two regions
+ * @MEMBLOCK_OVERLAPS: the two regions overlap each other, but are not the same
+ * @MEMBLOCK_EQUAL: both bases and sizes are equal, so the two regions are exactly the same
+ */
+enum memblock_overlap_type {
+	MEMBLOCK_NO_OVERLAPS,
+	MEMBLOCK_OVERLAPS,
+	MEMBLOCK_EQUAL,
+};
+
 /**
  * struct memblock_region - represents a memory region
  * @base: base address of the region
@@ -118,8 +130,8 @@ int memblock_reserve(phys_addr_t base, phys_addr_t size);
 int memblock_physmem_add(phys_addr_t base, phys_addr_t size);
 #endif
 void memblock_trim_memory(phys_addr_t align);
-bool memblock_overlaps_region(struct memblock_type *type,
-			      phys_addr_t base, phys_addr_t size);
+unsigned int memblock_overlaps_region(struct memblock_type *type,
+				      phys_addr_t base, phys_addr_t size);
 int memblock_mark_hotplug(phys_addr_t base, phys_addr_t size);
 int memblock_clear_hotplug(phys_addr_t base, phys_addr_t size);
 int memblock_mark_mirror(phys_addr_t base, phys_addr_t size);
@@ -486,7 +498,7 @@ bool memblock_is_memory(phys_addr_t addr);
 bool memblock_is_map_memory(phys_addr_t addr);
 bool memblock_is_region_memory(phys_addr_t base, phys_addr_t size);
 bool memblock_is_reserved(phys_addr_t addr);
-bool memblock_is_region_reserved(phys_addr_t base, phys_addr_t size);
+unsigned int memblock_is_region_reserved(phys_addr_t base, phys_addr_t size);
 
 void memblock_dump_all(void);
 
diff --git a/mm/memblock.c b/mm/memblock.c
index 25fd0626a9e7..948cc1bc3edf 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -175,24 +175,33 @@ static inline phys_addr_t memblock_cap_size(phys_addr_t base, phys_addr_t *size)
 /*
  * Address comparison utilities
  */
-static unsigned long __init_memblock memblock_addrs_overlap(phys_addr_t base1, phys_addr_t size1,
-				       phys_addr_t base2, phys_addr_t size2)
+static unsigned int __init_memblock memblock_addrs_overlap(phys_addr_t base1, phys_addr_t size1,
+							   phys_addr_t base2, phys_addr_t size2)
 {
-	return ((base1 < (base2 + size2)) && (base2 < (base1 + size1)));
+	if (base1 == base2 && size1 == size2)
+		return MEMBLOCK_EQUAL;
+
+	if ((base1 < (base2 + size2)) && (base2 < (base1 + size1)))
+		return MEMBLOCK_OVERLAPS;
+
+	return MEMBLOCK_NO_OVERLAPS;
 }
 
-bool __init_memblock memblock_overlaps_region(struct memblock_type *type,
-					phys_addr_t base, phys_addr_t size)
+unsigned int __init_memblock memblock_overlaps_region(struct memblock_type *type,
+						      phys_addr_t base, phys_addr_t size)
 {
-	unsigned long i;
+	unsigned long i, ret;
 
 	memblock_cap_size(base, &size);
 
-	for (i = 0; i < type->cnt; i++)
-		if (memblock_addrs_overlap(base, size, type->regions[i].base,
-					   type->regions[i].size))
-			break;
-	return i < type->cnt;
+	for (i = 0; i < type->cnt; i++) {
+		ret = memblock_addrs_overlap(base, size, type->regions[i].base,
+					     type->regions[i].size);
+		if (ret)
+			return ret;
+	}
+
+	return MEMBLOCK_NO_OVERLAPS;
 }
 
 /**
@@ -1857,9 +1866,11 @@ bool __init_memblock memblock_is_region_memory(phys_addr_t base, phys_addr_t siz
  * memory block.
  *
  * Return:
- * True if they intersect, false if not.
+ * MEMBLOCK_NO_OVERLAPS if there is no intersection,
+ * MEMBLOCK_OVERLAPS if they only intersect,
+ * MEMBLOCK_EQUAL if the region matches base and size to an reserved memory.
  */
-bool __init_memblock memblock_is_region_reserved(phys_addr_t base, phys_addr_t size)
+unsigned int __init_memblock memblock_is_region_reserved(phys_addr_t base, phys_addr_t size)
 {
 	return memblock_overlaps_region(&memblock.reserved, base, size);
 }
-- 
2.40.0



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

* [PATCH 2/2] of: fdt: Allow the kernel to mark nomap regions received from fdt
  2023-04-06 15:14 [PATCH 0/2] Fix Random Kernel panic from when fail to reserve memory Lucas Tanure
  2023-04-06 15:14 ` [PATCH 1/2] memblock: Differentiate regions overlap from both regions being the same Lucas Tanure
@ 2023-04-06 15:14 ` Lucas Tanure
  2023-04-06 15:48   ` Rob Herring
  1 sibling, 1 reply; 5+ messages in thread
From: Lucas Tanure @ 2023-04-06 15:14 UTC (permalink / raw)
  To: Rob Herring, Frank Rowand, Mike Rapoport, Andrew Morton
  Cc: devicetree, linux-kernel, linux-mm, jbrunet, linux-amlogic,
	linux-arm-kernel, martin.blumenstingl, narmstrong, stefan,
	Lucas Tanure

Reserved regions can be described in FDT and device trees, but FDT doesn't
provide the related flags, like nomap.
So allow the kernel to mark regions where the base and size received from
the device tree are the same as the base and region on FDT.
Here we trust that the device tree has a more updated description of the
region than the one received from FDT.

Signed-off-by: Lucas Tanure <tanure@linux.com>
---
 drivers/of/fdt.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index d1a68b6d03b3..754a7ea4f45c 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -482,11 +482,13 @@ static int __init early_init_dt_reserve_memory(phys_addr_t base,
 	if (nomap) {
 		/*
 		 * If the memory is already reserved (by another region), we
-		 * should not allow it to be marked nomap, but don't worry
-		 * if the region isn't memory as it won't be mapped.
+		 * should not allow it to be marked nomap, unless is the exact same region
+		 * (same base and size), which the kernel knows better and should be allowed to mark
+		 *  it as nomap.
+		 * But don't worry if the region isn't memory as it won't be mapped.
 		 */
-		if (memblock_overlaps_region(&memblock.memory, base, size) &&
-		    memblock_is_region_reserved(base, size))
+		if (memblock_overlaps_region(&memblock.memory, base, size) == MEMBLOCK_OVERLAPS &&
+		    memblock_is_region_reserved(base, size) == MEMBLOCK_OVERLAPS)
 			return -EBUSY;
 
 		return memblock_mark_nomap(base, size);
-- 
2.40.0



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

* Re: [PATCH 2/2] of: fdt: Allow the kernel to mark nomap regions received from fdt
  2023-04-06 15:14 ` [PATCH 2/2] of: fdt: Allow the kernel to mark nomap regions received from fdt Lucas Tanure
@ 2023-04-06 15:48   ` Rob Herring
  2023-04-06 16:06     ` Neil Armstrong
  0 siblings, 1 reply; 5+ messages in thread
From: Rob Herring @ 2023-04-06 15:48 UTC (permalink / raw)
  To: Lucas Tanure
  Cc: Frank Rowand, Mike Rapoport, Andrew Morton, devicetree,
	linux-kernel, linux-mm, jbrunet, linux-amlogic, linux-arm-kernel,
	martin.blumenstingl, narmstrong, stefan

On Thu, Apr 6, 2023 at 10:14 AM Lucas Tanure <tanure@linux.com> wrote:
>
> Reserved regions can be described in FDT and device trees, but FDT doesn't
> provide the related flags, like nomap.

It took me a minute to understand what you meant by FDT vs. device
trees. Use the exact things you are talking about: /memreserve/ and
/reserved-memory node.

> So allow the kernel to mark regions where the base and size received from
> the device tree are the same as the base and region on FDT.
> Here we trust that the device tree has a more updated description of the
> region than the one received from FDT.
>
> Signed-off-by: Lucas Tanure <tanure@linux.com>
> ---
>  drivers/of/fdt.c | 10 ++++++----
>  1 file changed, 6 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index d1a68b6d03b3..754a7ea4f45c 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -482,11 +482,13 @@ static int __init early_init_dt_reserve_memory(phys_addr_t base,
>         if (nomap) {
>                 /*
>                  * If the memory is already reserved (by another region), we
> -                * should not allow it to be marked nomap, but don't worry
> -                * if the region isn't memory as it won't be mapped.
> +                * should not allow it to be marked nomap, unless is the exact same region
> +                * (same base and size), which the kernel knows better and should be allowed to mark
> +                *  it as nomap.
> +                * But don't worry if the region isn't memory as it won't be mapped.
>                  */
> -               if (memblock_overlaps_region(&memblock.memory, base, size) &&
> -                   memblock_is_region_reserved(base, size))
> +               if (memblock_overlaps_region(&memblock.memory, base, size) == MEMBLOCK_OVERLAPS &&
> +                   memblock_is_region_reserved(base, size) == MEMBLOCK_OVERLAPS)

Won't this fail to work as IIRC memblock will merge regions when they
are adjacent and have the same atrributes.

Perhaps instead, the DT code should ignore any /memreserve/ entries
that are also in /reserved-memory.

I would suggest just reverse the order they are processed, but I
suspect that might cause some regression. This code is all fragile
especially with platforms putting in 100 regions.

Finally, perhaps fix u-boot. The reason the reserved location goes in
both places was to support an OS not supporting /reserved-memory. I
think that support has been in place for a lot longer than anyone
would care about.

Rob


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

* Re: [PATCH 2/2] of: fdt: Allow the kernel to mark nomap regions received from fdt
  2023-04-06 15:48   ` Rob Herring
@ 2023-04-06 16:06     ` Neil Armstrong
  0 siblings, 0 replies; 5+ messages in thread
From: Neil Armstrong @ 2023-04-06 16:06 UTC (permalink / raw)
  To: Rob Herring, Lucas Tanure
  Cc: Frank Rowand, Mike Rapoport, Andrew Morton, devicetree,
	linux-kernel, linux-mm, jbrunet, linux-amlogic, linux-arm-kernel,
	martin.blumenstingl, narmstrong, stefan

On 06/04/2023 17:48, Rob Herring wrote:
> On Thu, Apr 6, 2023 at 10:14 AM Lucas Tanure <tanure@linux.com> wrote:
>>
>> Reserved regions can be described in FDT and device trees, but FDT doesn't
>> provide the related flags, like nomap.
> 
> It took me a minute to understand what you meant by FDT vs. device
> trees. Use the exact things you are talking about: /memreserve/ and
> /reserved-memory node.
> 
>> So allow the kernel to mark regions where the base and size received from
>> the device tree are the same as the base and region on FDT.
>> Here we trust that the device tree has a more updated description of the
>> region than the one received from FDT.
>>
>> Signed-off-by: Lucas Tanure <tanure@linux.com>
>> ---
>>   drivers/of/fdt.c | 10 ++++++----
>>   1 file changed, 6 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
>> index d1a68b6d03b3..754a7ea4f45c 100644
>> --- a/drivers/of/fdt.c
>> +++ b/drivers/of/fdt.c
>> @@ -482,11 +482,13 @@ static int __init early_init_dt_reserve_memory(phys_addr_t base,
>>          if (nomap) {
>>                  /*
>>                   * If the memory is already reserved (by another region), we
>> -                * should not allow it to be marked nomap, but don't worry
>> -                * if the region isn't memory as it won't be mapped.
>> +                * should not allow it to be marked nomap, unless is the exact same region
>> +                * (same base and size), which the kernel knows better and should be allowed to mark
>> +                *  it as nomap.
>> +                * But don't worry if the region isn't memory as it won't be mapped.
>>                   */
>> -               if (memblock_overlaps_region(&memblock.memory, base, size) &&
>> -                   memblock_is_region_reserved(base, size))
>> +               if (memblock_overlaps_region(&memblock.memory, base, size) == MEMBLOCK_OVERLAPS &&
>> +                   memblock_is_region_reserved(base, size) == MEMBLOCK_OVERLAPS)
> 
> Won't this fail to work as IIRC memblock will merge regions when they
> are adjacent and have the same atrributes.
> 
> Perhaps instead, the DT code should ignore any /memreserve/ entries
> that are also in /reserved-memory.
> 
> I would suggest just reverse the order they are processed, but I
> suspect that might cause some regression. This code is all fragile
> especially with platforms putting in 100 regions.
> 
> Finally, perhaps fix u-boot. The reason the reserved location goes in
> both places was to support an OS not supporting /reserved-memory. I
> think that support has been in place for a lot longer than anyone
> would care about.

Fixing U-Boot won't fix already tagged and in-the-field mainline u-boot
releases that adds /memreserve/ entries, so yes u-boot should be definitely
fixed but Linux should ignore the /memreserve/ entries when they matches
an /reserved-memory node like when the U-Boot /memreserve/ code was added.

Neil

> 
> Rob
> 
> _______________________________________________
> linux-amlogic mailing list
> linux-amlogic@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-amlogic



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

end of thread, other threads:[~2023-04-06 16:06 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-06 15:14 [PATCH 0/2] Fix Random Kernel panic from when fail to reserve memory Lucas Tanure
2023-04-06 15:14 ` [PATCH 1/2] memblock: Differentiate regions overlap from both regions being the same Lucas Tanure
2023-04-06 15:14 ` [PATCH 2/2] of: fdt: Allow the kernel to mark nomap regions received from fdt Lucas Tanure
2023-04-06 15:48   ` Rob Herring
2023-04-06 16:06     ` Neil Armstrong

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox