Re: [PATCH 0/2] of: remove reserved regions count restriction

2021-11-22 Thread Calvin Zhang
On Sun, Nov 21, 2021 at 08:43:47AM +0200, Mike Rapoport wrote:
>On Fri, Nov 19, 2021 at 03:58:17PM +0800, Calvin Zhang wrote:
>> The count of reserved regions in /reserved-memory was limited because
>> the struct reserved_mem array was defined statically. This series sorts
>> out reserved memory code and allocates that array from early allocator.
>> 
>> Note: reserved region with fixed location must be reserved before any
>> memory allocation. While struct reserved_mem array should be allocated
>> after allocator is activated. We make early_init_fdt_scan_reserved_mem()
>> do reservation only and add another call to initialize reserved memory.
>> So arch code have to change for it.
>
>I think much simpler would be to use the same constant for sizing
>memblock.reserved and reserved_mem arrays.
>
>If there is too much reserved regions in the device tree, reserving them in
>memblock will fail anyway because memblock also starts with static array
>for memblock.reserved, so doing one pass with memblock_reserve() and
>another to set up reserved_mem wouldn't help anyway.

Yes. This happens only if there are two many fixed reserved regions.
memblock.reserved can be resized after paging.

I also find another problem. Initializing dynamic reservation after
paging would fail to mark it no-map because no-map flag works when doing
direct mapping. This seems to be a circular dependency.

Thank You,
Calvin


Re: [PATCH 2/2] of: reserved_mem: Remove reserved regions count restriction

2021-11-19 Thread Calvin Zhang
On Fri, Nov 19, 2021 at 11:56:08AM +0200, Andy Shevchenko wrote:
>On Fri, Nov 19, 2021 at 03:58:19PM +0800, Calvin Zhang wrote:
>> Change to allocate reserved_mems dynamically. Static reserved regions
>> must be reserved before any memblock allocations. The reserved_mems
>> array couldn't be allocated until memblock and linear mapping are ready.
>> 
>> So move the allocation and initialization of records and reserved memory
>> from early_init_fdt_scan_reserved_mem() to of_reserved_mem_init().
>
>>  arch/arc/mm/init.c |  3 ++
>>  arch/arm/kernel/setup.c|  2 +
>>  arch/arm64/kernel/setup.c  |  3 ++
>>  arch/csky/kernel/setup.c   |  3 ++
>>  arch/h8300/kernel/setup.c  |  2 +
>>  arch/mips/kernel/setup.c   |  3 ++
>>  arch/nds32/kernel/setup.c  |  3 ++
>>  arch/nios2/kernel/setup.c  |  2 +
>>  arch/openrisc/kernel/setup.c   |  3 ++
>>  arch/powerpc/kernel/setup-common.c |  3 ++
>>  arch/riscv/kernel/setup.c  |  2 +
>>  arch/sh/kernel/setup.c |  3 ++
>>  arch/xtensa/kernel/setup.c |  2 +
>
>Isn't x86 missed? Is it on purpose?
>Would be nice to have this in the commit message or fixed accordingly.
AFAIK, x86 doesn't reserve memory through "/reserved-memory" node until now.
Actually, I got the arch list from callers of
early_init_fdt_scan_reserved_mem().
>
>-- 
>With Best Regards,
>Andy Shevchenko
>
>
>
Thanks,
Calvin


Re: [PATCH 2/2] of: reserved_mem: Remove reserved regions count restriction

2021-11-19 Thread Calvin Zhang
On Fri, Nov 19, 2021 at 11:56:08AM +0200, Andy Shevchenko wrote:
>On Fri, Nov 19, 2021 at 03:58:19PM +0800, Calvin Zhang wrote:
>> Change to allocate reserved_mems dynamically. Static reserved regions
>> must be reserved before any memblock allocations. The reserved_mems
>> array couldn't be allocated until memblock and linear mapping are ready.
>> 
>> So move the allocation and initialization of records and reserved memory
>> from early_init_fdt_scan_reserved_mem() to of_reserved_mem_init().
>
>>  arch/arc/mm/init.c |  3 ++
>>  arch/arm/kernel/setup.c|  2 +
>>  arch/arm64/kernel/setup.c  |  3 ++
>>  arch/csky/kernel/setup.c   |  3 ++
>>  arch/h8300/kernel/setup.c  |  2 +
>>  arch/mips/kernel/setup.c   |  3 ++
>>  arch/nds32/kernel/setup.c  |  3 ++
>>  arch/nios2/kernel/setup.c  |  2 +
>>  arch/openrisc/kernel/setup.c   |  3 ++
>>  arch/powerpc/kernel/setup-common.c |  3 ++
>>  arch/riscv/kernel/setup.c  |  2 +
>>  arch/sh/kernel/setup.c |  3 ++
>>  arch/xtensa/kernel/setup.c |  2 +
>
>Isn't x86 missed? Is it on purpose?
>Would be nice to have this in the commit message or fixed accordingly.
AFAIK, x86 doesn't reserve memory through "/reserved-memory" node until now.
Actually, I got the arch list from callers of
early_init_fdt_scan_reserved_mem().
>
>-- 
>With Best Regards,
>Andy Shevchenko
>
>
>

Thanks,
Calvin


[PATCH 2/2] of: reserved_mem: Remove reserved regions count restriction

2021-11-19 Thread Calvin Zhang
Change to allocate reserved_mems dynamically. Static reserved regions
must be reserved before any memblock allocations. The reserved_mems
array couldn't be allocated until memblock and linear mapping are ready.

So move the allocation and initialization of records and reserved memory
from early_init_fdt_scan_reserved_mem() to of_reserved_mem_init().

Signed-off-by: Calvin Zhang 
---
 arch/arc/mm/init.c |  3 ++
 arch/arm/kernel/setup.c|  2 +
 arch/arm64/kernel/setup.c  |  3 ++
 arch/csky/kernel/setup.c   |  3 ++
 arch/h8300/kernel/setup.c  |  2 +
 arch/mips/kernel/setup.c   |  3 ++
 arch/nds32/kernel/setup.c  |  3 ++
 arch/nios2/kernel/setup.c  |  2 +
 arch/openrisc/kernel/setup.c   |  3 ++
 arch/powerpc/kernel/setup-common.c |  3 ++
 arch/riscv/kernel/setup.c  |  2 +
 arch/sh/kernel/setup.c |  3 ++
 arch/xtensa/kernel/setup.c |  2 +
 drivers/of/fdt.c   |  1 -
 drivers/of/of_reserved_mem.c   | 66 --
 15 files changed, 79 insertions(+), 22 deletions(-)

diff --git a/arch/arc/mm/init.c b/arch/arc/mm/init.c
index ce4e939a7f07..a75f0e693f37 100644
--- a/arch/arc/mm/init.c
+++ b/arch/arc/mm/init.c
@@ -10,6 +10,7 @@
 #include 
 #endif
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -165,6 +166,8 @@ void __init setup_arch_memory(void)
 
 #endif /* CONFIG_HIGHMEM */
 
+   of_reserved_mem_init();
+
free_area_init(max_zone_pfn);
 }
 
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 284a80c0b6e1..e76737effbf4 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1153,6 +1154,7 @@ void __init setup_arch(char **cmdline_p)
early_ioremap_reset();
 
paging_init(mdesc);
+   of_reserved_mem_init();
kasan_init();
request_standard_resources(mdesc);
 
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index be5f85b0a24d..4624e5193d6e 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -339,6 +340,8 @@ void __init __no_sanitize_address setup_arch(char 
**cmdline_p)
 
paging_init();
 
+   of_reserved_mem_init();
+
acpi_table_upgrade();
 
/* Parse the ACPI tables for possible boot-time configuration */
diff --git a/arch/csky/kernel/setup.c b/arch/csky/kernel/setup.c
index c64e7be2045b..40878906644d 100644
--- a/arch/csky/kernel/setup.c
+++ b/arch/csky/kernel/setup.c
@@ -6,6 +6,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -64,6 +65,8 @@ static void __init csky_memblock_init(void)
 #endif
memblock_set_current_limit(PFN_PHYS(max_low_pfn));
 
+   of_reserved_mem_init();
+
dma_contiguous_reserve(0);
 
free_area_init(max_zone_pfn);
diff --git a/arch/h8300/kernel/setup.c b/arch/h8300/kernel/setup.c
index 61091a76eb7e..0f0ec72a260e 100644
--- a/arch/h8300/kernel/setup.c
+++ b/arch/h8300/kernel/setup.c
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -87,6 +88,7 @@ static void __init bootmem_init(void)
 
early_init_fdt_reserve_self();
early_init_fdt_scan_reserved_mem();
+   of_reserved_mem_init();
 
memblock_dump_all();
 }
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index f979adfd4fc2..053a10d80cb9 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -776,6 +777,8 @@ void __init setup_arch(char **cmdline_p)
cpu_cache_init();
paging_init();
 
+   of_reserved_mem_init();
+
memblock_dump_all();
 }
 
diff --git a/arch/nds32/kernel/setup.c b/arch/nds32/kernel/setup.c
index b3d34d646652..1054804526c5 100644
--- a/arch/nds32/kernel/setup.c
+++ b/arch/nds32/kernel/setup.c
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -301,6 +302,8 @@ void __init setup_arch(char **cmdline_p)
/* paging_init() sets up the MMU and marks all pages as reserved */
paging_init();
 
+   of_reserved_mem_init();
+
/* invalidate all TLB entries because the new mapping is created */
__nds32__tlbop_flua();
 
diff --git a/arch/nios2/kernel/setup.c b/arch/nios2/kernel/setup.c
index 40bc8fb75e0b..7e40e90bc3cd 100644
--- a/arch/nios2/kernel/setup.c
+++ b/arch/nios2/kernel/setup.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -173,6 +174,7 @@ void __init setup_arch(char **cmdline_p)
 
early_init_fdt_reserve_self();
early_init_fdt_scan_reserved_mem();
+   of_reserved_mem_init();
 
unflatten_and_copy_device_tree();
 
diff --git a/arch

[PATCH 1/2] of: Sort reserved_mem related code

2021-11-19 Thread Calvin Zhang
Move code about parsing /reserved-memory and initializing of
reserved_mems array to of_reserved_mem.c for better modularity.

Rename array name from reserved_mem to reserved_mems to distinguish
from type definition.

Signed-off-by: Calvin Zhang 
---
 drivers/of/fdt.c| 108 +
 drivers/of/of_private.h |  12 ++-
 drivers/of/of_reserved_mem.c| 163 ++--
 include/linux/of_reserved_mem.h |   4 +
 4 files changed, 149 insertions(+), 138 deletions(-)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index bdca35284ceb..445af4e69300 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -80,7 +80,7 @@ void __init of_fdt_limit_memory(int limit)
}
 }
 
-static bool of_fdt_device_is_available(const void *blob, unsigned long node)
+bool of_fdt_device_is_available(const void *blob, unsigned long node)
 {
const char *status = fdt_getprop(blob, node, "status", NULL);
 
@@ -476,7 +476,7 @@ void *initial_boot_params __ro_after_init;
 
 static u32 of_fdt_crc32;
 
-static int __init early_init_dt_reserve_memory_arch(phys_addr_t base,
+int __init early_init_dt_reserve_memory_arch(phys_addr_t base,
phys_addr_t size, bool nomap)
 {
if (nomap) {
@@ -492,108 +492,6 @@ static int __init 
early_init_dt_reserve_memory_arch(phys_addr_t base,
return memblock_reserve(base, size);
 }
 
-/*
- * __reserved_mem_reserve_reg() - reserve all memory described in 'reg' 
property
- */
-static int __init __reserved_mem_reserve_reg(unsigned long node,
-const char *uname)
-{
-   int t_len = (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32);
-   phys_addr_t base, size;
-   int len;
-   const __be32 *prop;
-   int first = 1;
-   bool nomap;
-
-   prop = of_get_flat_dt_prop(node, "reg", );
-   if (!prop)
-   return -ENOENT;
-
-   if (len && len % t_len != 0) {
-   pr_err("Reserved memory: invalid reg property in '%s', skipping 
node.\n",
-  uname);
-   return -EINVAL;
-   }
-
-   nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL;
-
-   while (len >= t_len) {
-   base = dt_mem_next_cell(dt_root_addr_cells, );
-   size = dt_mem_next_cell(dt_root_size_cells, );
-
-   if (size &&
-   early_init_dt_reserve_memory_arch(base, size, nomap) == 0)
-   pr_debug("Reserved memory: reserved region for node 
'%s': base %pa, size %lu MiB\n",
-   uname, , (unsigned long)(size / SZ_1M));
-   else
-   pr_info("Reserved memory: failed to reserve memory for 
node '%s': base %pa, size %lu MiB\n",
-   uname, , (unsigned long)(size / SZ_1M));
-
-   len -= t_len;
-   if (first) {
-   fdt_reserved_mem_save_node(node, uname, base, size);
-   first = 0;
-   }
-   }
-   return 0;
-}
-
-/*
- * __reserved_mem_check_root() - check if #size-cells, #address-cells provided
- * in /reserved-memory matches the values supported by the current 
implementation,
- * also check if ranges property has been provided
- */
-static int __init __reserved_mem_check_root(unsigned long node)
-{
-   const __be32 *prop;
-
-   prop = of_get_flat_dt_prop(node, "#size-cells", NULL);
-   if (!prop || be32_to_cpup(prop) != dt_root_size_cells)
-   return -EINVAL;
-
-   prop = of_get_flat_dt_prop(node, "#address-cells", NULL);
-   if (!prop || be32_to_cpup(prop) != dt_root_addr_cells)
-   return -EINVAL;
-
-   prop = of_get_flat_dt_prop(node, "ranges", NULL);
-   if (!prop)
-   return -EINVAL;
-   return 0;
-}
-
-/*
- * fdt_scan_reserved_mem() - scan a single FDT node for reserved memory
- */
-static int __init fdt_scan_reserved_mem(void)
-{
-   int node, child;
-   const void *fdt = initial_boot_params;
-
-   node = fdt_path_offset(fdt, "/reserved-memory");
-   if (node < 0)
-   return -ENODEV;
-
-   if (__reserved_mem_check_root(node) != 0) {
-   pr_err("Reserved memory: unsupported node format, ignoring\n");
-   return -EINVAL;
-   }
-
-   fdt_for_each_subnode(child, fdt, node) {
-   const char *uname;
-   int err;
-
-   if (!of_fdt_device_is_available(fdt, child))
-   continue;
-
-   uname = fdt_get_name(fdt, child, NULL);
-
-   err = __reserved_mem_reserve_reg(child, uname);
-   if (err == -ENOENT && of_get_flat_dt_prop(child, "size", NULL))
-   fdt_reserved_mem_save_

[PATCH 0/2] of: remove reserved regions count restriction

2021-11-19 Thread Calvin Zhang
The count of reserved regions in /reserved-memory was limited because
the struct reserved_mem array was defined statically. This series sorts
out reserved memory code and allocates that array from early allocator.

Note: reserved region with fixed location must be reserved before any
memory allocation. While struct reserved_mem array should be allocated
after allocator is activated. We make early_init_fdt_scan_reserved_mem()
do reservation only and add another call to initialize reserved memory.
So arch code have to change for it.

I'm only familiar with arm and arm64 architectures. Approvals from arch
maintainers are required. Thank you all.

Calvin Zhang (2):
  of: Sort reserved_mem related code
  of: reserved_mem: Remove reserved regions count restriction

 arch/arc/mm/init.c |   3 +
 arch/arm/kernel/setup.c|   2 +
 arch/arm64/kernel/setup.c  |   3 +
 arch/csky/kernel/setup.c   |   3 +
 arch/h8300/kernel/setup.c  |   2 +
 arch/mips/kernel/setup.c   |   3 +
 arch/nds32/kernel/setup.c  |   3 +
 arch/nios2/kernel/setup.c  |   2 +
 arch/openrisc/kernel/setup.c   |   3 +
 arch/powerpc/kernel/setup-common.c |   3 +
 arch/riscv/kernel/setup.c  |   2 +
 arch/sh/kernel/setup.c |   3 +
 arch/xtensa/kernel/setup.c |   2 +
 drivers/of/fdt.c   | 107 +---
 drivers/of/of_private.h|  12 +-
 drivers/of/of_reserved_mem.c   | 189 -
 include/linux/of_reserved_mem.h|   4 +
 17 files changed, 207 insertions(+), 139 deletions(-)

-- 
2.30.2