From patchwork Fri Nov 19 07:58:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Calvin Zhang X-Patchwork-Id: 12628431 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F2E19C433FE for ; Fri, 19 Nov 2021 08:01:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C8C6661B04 for ; Fri, 19 Nov 2021 08:01:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233682AbhKSIET (ORCPT ); Fri, 19 Nov 2021 03:04:19 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55730 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229879AbhKSIET (ORCPT ); Fri, 19 Nov 2021 03:04:19 -0500 Received: from mail-pf1-x435.google.com (mail-pf1-x435.google.com [IPv6:2607:f8b0:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 07996C061574; Fri, 19 Nov 2021 00:01:18 -0800 (PST) Received: by mail-pf1-x435.google.com with SMTP id g18so8716719pfk.5; Fri, 19 Nov 2021 00:01:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=EE3SEPXoBbvJsiDAeji5FCMph0V1ZFJAuPncPXWzYuc=; b=kh9rM6hD/csU0psarGvH1deMLlvio0l/tW7tpWG4HVab9CRAttPkIbjpp6FapiotvQ v+n0cwlXmnNVtZyxR2b+uBvS92Lz153yWkr/cmJi0KHaXXnX6oK4zGfI52zhRETcTN6N 44TPhShDpdj0EetsUVqeCGFQZDOsL/oEJvHmtBHBSHy9DnuUAGRpAG9+ELmu3MR1kDaN iqkSLqMtydAGnIOFHe7nWWreBeqbUKunO3mV0FfI1thtKKXNGKBhhM0ty73iKv+AEnQk x+/KZIOChNy8YO3PBh934tpq4Mk9ZCbnOdbbPaupoCRfm5APF2mDupRZqzwZqTg3CTPL TfBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=EE3SEPXoBbvJsiDAeji5FCMph0V1ZFJAuPncPXWzYuc=; b=V6mZWbAJrKuD0xPdHFrtbTVS9fseGDeXWuEHocfv6FwXNKbaxRotSX941TTspcJIkF o8Mu6zlZuTwZxZICNpJuReFijXdPhnCk9LE7mlRS653yPRjpdb0eSex0ZfmEpsMECJhI 5WFJQHvnZ4/jIZVpHDK84i6/cNTW47YUoW3TNOMjIgqU3LxiaLOwS//sqsMyWyaD2ZJk 54nlJWDcRa42tJ0A8qUusa4DP6/KYANOxOd5bIjTf/7UiqEQMbJBqnN58VO5vZdZ3RcE zJJcaqE1EQgZexGS4lnxuNF2LRrK8zuL4jtkZzoHHCrBuJJU4bQGuEhfz6nhbr70tkwp J/HQ== X-Gm-Message-State: AOAM530eoA3UI02QGEgifzSBs/OyYFPdG3pxWMxsRkA0RI69TYLv6U4z At0zox/CcINnjlflUxX3yoI= X-Google-Smtp-Source: ABdhPJzldH7ipqqyeM+oT5d6Qzi/yvo/sIXQ5tPUpktsTjymUZzDLBV0pBKyCmXVkuqv/SB3PAreQA== X-Received: by 2002:a63:b25d:: with SMTP id t29mr16036769pgo.79.1637308877488; Fri, 19 Nov 2021 00:01:17 -0800 (PST) Received: from localhost.localdomain ([103.99.179.247]) by smtp.gmail.com with ESMTPSA id o6sm1791259pfh.70.2021.11.19.00.00.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 19 Nov 2021 00:01:17 -0800 (PST) From: Calvin Zhang To: Vineet Gupta , Russell King , Catalin Marinas , Will Deacon , Guo Ren , Yoshinori Sato , Thomas Bogendoerfer , Nick Hu , Greentime Hu , Vincent Chen , Dinh Nguyen , Jonas Bonn , Stefan Kristiansson , Stafford Horne , Michael Ellerman , Benjamin Herrenschmidt , Paul Mackerras , Paul Walmsley , Palmer Dabbelt , Albert Ou , Rich Felker , Chris Zankel , Max Filippov , Rob Herring , Frank Rowand , Mike Rapoport , Andrew Morton , David Hildenbrand , Kefeng Wang , Vladimir Isaev , Calvin Zhang , Arnd Bergmann , "Russell King (Oracle)" , Wolfram Sang , Guenter Roeck , Marc Zyngier , David Brazdil , Mark Rutland , Andrey Konovalov , Anshuman Khandual , Souptick Joarder , Jinyang He , Alexander Sverdlin , Serge Semin , Geert Uytterhoeven , Ley Foon Tan , Andreas Oetken , Randy Dunlap , Christophe JAILLET , Christophe Leroy , Andy Shevchenko , Zhang Yunkai , Markus Elfring , Ganesh Goudar , "Aneesh Kumar K.V" , Atish Patra , Anup Patel , Nick Kossifidis , Alexandre Ghiti , Vitaly Wool Cc: "Rafael J. Wysocki" , Guo Ren , Rob Herring , Tiezhu Yang , Mauri Sandberg , Palmer Dabbelt , linux-snps-arc@lists.infradead.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-csky@vger.kernel.org, uclinux-h8-devel@lists.sourceforge.jp, linux-mips@vger.kernel.org, openrisc@lists.librecores.org, linuxppc-dev@lists.ozlabs.org, linux-riscv@lists.infradead.org, linux-sh@vger.kernel.org, linux-xtensa@linux-xtensa.org, devicetree@vger.kernel.org Subject: [PATCH 1/2] of: Sort reserved_mem related code Date: Fri, 19 Nov 2021 15:58:18 +0800 Message-Id: <20211119075844.2902592-2-calvinzhang.cool@gmail.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211119075844.2902592-1-calvinzhang.cool@gmail.com> References: <20211119075844.2902592-1-calvinzhang.cool@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org 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", &len); - 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, &prop); - size = dt_mem_next_cell(dt_root_size_cells, &prop); - - 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, &base, (unsigned long)(size / SZ_1M)); - else - pr_info("Reserved memory: failed to reserve memory for node '%s': base %pa, size %lu MiB\n", - uname, &base, (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_node(child, uname, 0, 0); - } - return 0; -} - /* * fdt_reserve_elfcorehdr() - reserves memory for elf core header * @@ -642,7 +540,7 @@ void __init early_init_fdt_scan_reserved_mem(void) } fdt_scan_reserved_mem(); - fdt_init_reserved_mem(); + of_reserved_mem_init(); fdt_reserve_elfcorehdr(); } diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h index 9324483397f6..88b67f8ed698 100644 --- a/drivers/of/of_private.h +++ b/drivers/of/of_private.h @@ -163,8 +163,14 @@ static inline int of_dma_get_range(struct device_node *np, } #endif -void fdt_init_reserved_mem(void); -void fdt_reserved_mem_save_node(unsigned long node, const char *uname, - phys_addr_t base, phys_addr_t size); +bool of_fdt_device_is_available(const void *blob, unsigned long node); +int early_init_dt_reserve_memory_arch(phys_addr_t base, + phys_addr_t size, bool nomap); +#ifdef CONFIG_OF_RESERVED_MEM +int fdt_scan_reserved_mem(void); +#else +static inline int fdt_scan_reserved_mem(void) { } +#endif + #endif /* _LINUX_OF_PRIVATE_H */ diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c index 9c0fb962c22b..784cfc5cd251 100644 --- a/drivers/of/of_reserved_mem.c +++ b/drivers/of/of_reserved_mem.c @@ -20,13 +20,14 @@ #include #include #include +#include #include #include #include "of_private.h" #define MAX_RESERVED_REGIONS 64 -static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS]; +static struct reserved_mem reserved_mems[MAX_RESERVED_REGIONS]; static int reserved_mem_count; static int __init early_init_dt_alloc_reserved_memory_arch(phys_addr_t size, @@ -56,12 +57,12 @@ static int __init early_init_dt_alloc_reserved_memory_arch(phys_addr_t size, /* * fdt_reserved_mem_save_node() - save fdt node for second pass initialization */ -void __init fdt_reserved_mem_save_node(unsigned long node, const char *uname, +static void __init fdt_reserved_mem_save_node(unsigned long node, const char *uname, phys_addr_t base, phys_addr_t size) { - struct reserved_mem *rmem = &reserved_mem[reserved_mem_count]; + struct reserved_mem *rmem = &reserved_mems[reserved_mem_count]; - if (reserved_mem_count == ARRAY_SIZE(reserved_mem)) { + if (reserved_mem_count == ARRAY_SIZE(reserved_mems)) { pr_err("not enough space for all defined regions.\n"); return; } @@ -173,29 +174,105 @@ static const struct of_device_id __rmem_of_table_sentinel __used __section("__reservedmem_of_table_end"); /* - * __reserved_mem_init_node() - call region specific reserved memory init code + * __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_init_node(struct reserved_mem *rmem) +static int __init __reserved_mem_check_root(unsigned long node) { - extern const struct of_device_id __reservedmem_of_table[]; - const struct of_device_id *i; - int ret = -ENOENT; + const __be32 *prop; - for (i = __reservedmem_of_table; i < &__rmem_of_table_sentinel; i++) { - reservedmem_of_init_fn initfn = i->data; - const char *compat = i->compatible; + prop = of_get_flat_dt_prop(node, "#size-cells", NULL); + if (!prop || be32_to_cpup(prop) != dt_root_size_cells) + return -EINVAL; - if (!of_flat_dt_is_compatible(rmem->fdt_node, compat)) - continue; + prop = of_get_flat_dt_prop(node, "#address-cells", NULL); + if (!prop || be32_to_cpup(prop) != dt_root_addr_cells) + return -EINVAL; - ret = initfn(rmem); - if (ret == 0) { - pr_info("initialized node %s, compatible id %s\n", - rmem->name, compat); - break; + prop = of_get_flat_dt_prop(node, "ranges", NULL); + if (!prop) + return -EINVAL; + return 0; +} + +/* + * __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", &len); + 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, &prop); + size = dt_mem_next_cell(dt_root_size_cells, &prop); + + 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, &base, (unsigned long)(size / SZ_1M)); + else + pr_info("Reserved memory: failed to reserve memory for node '%s': base %pa, size %lu MiB\n", + uname, &base, (unsigned long)(size / SZ_1M)); + + len -= t_len; + if (first) { + fdt_reserved_mem_save_node(node, uname, base, size); + first = 0; } } - return ret; + return 0; +} + +/* + * fdt_scan_reserved_mem() - scan a single FDT node for reserved memory + */ +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_node(child, uname, 0, 0); + } + return 0; } static int __init __rmem_cmp(const void *a, const void *b) @@ -228,13 +305,13 @@ static void __init __rmem_check_for_overlap(void) if (reserved_mem_count < 2) return; - sort(reserved_mem, reserved_mem_count, sizeof(reserved_mem[0]), + sort(reserved_mems, reserved_mem_count, sizeof(reserved_mems[0]), __rmem_cmp, NULL); for (i = 0; i < reserved_mem_count - 1; i++) { struct reserved_mem *this, *next; - this = &reserved_mem[i]; - next = &reserved_mem[i + 1]; + this = &reserved_mems[i]; + next = &reserved_mems[i + 1]; if (this->base + this->size > next->base) { phys_addr_t this_end, next_end; @@ -248,10 +325,36 @@ static void __init __rmem_check_for_overlap(void) } } +/* + * __reserved_mem_init_node() - call region specific reserved memory init code + */ +static int __init __reserved_mem_init_node(struct reserved_mem *rmem) +{ + extern const struct of_device_id __reservedmem_of_table[]; + const struct of_device_id *i; + int ret = -ENOENT; + + for (i = __reservedmem_of_table; i < &__rmem_of_table_sentinel; i++) { + reservedmem_of_init_fn initfn = i->data; + const char *compat = i->compatible; + + if (!of_flat_dt_is_compatible(rmem->fdt_node, compat)) + continue; + + ret = initfn(rmem); + if (ret == 0) { + pr_info("initialized node %s, compatible id %s\n", + rmem->name, compat); + break; + } + } + return ret; +} + /** - * fdt_init_reserved_mem() - allocate and init all saved reserved memory regions + * of_reserved_mem_init() - allocate and init all saved reserved memory regions */ -void __init fdt_init_reserved_mem(void) +void __init of_reserved_mem_init(void) { int i; @@ -259,7 +362,7 @@ void __init fdt_init_reserved_mem(void) __rmem_check_for_overlap(); for (i = 0; i < reserved_mem_count; i++) { - struct reserved_mem *rmem = &reserved_mem[i]; + struct reserved_mem *rmem = &reserved_mems[i]; unsigned long node = rmem->fdt_node; int len; const __be32 *prop; @@ -299,8 +402,8 @@ static inline struct reserved_mem *__find_rmem(struct device_node *node) return NULL; for (i = 0; i < reserved_mem_count; i++) - if (reserved_mem[i].phandle == node->phandle) - return &reserved_mem[i]; + if (reserved_mems[i].phandle == node->phandle) + return &reserved_mems[i]; return NULL; } @@ -442,8 +545,8 @@ struct reserved_mem *of_reserved_mem_lookup(struct device_node *np) name = kbasename(np->full_name); for (i = 0; i < reserved_mem_count; i++) - if (!strcmp(reserved_mem[i].name, name)) - return &reserved_mem[i]; + if (!strcmp(reserved_mems[i].name, name)) + return &reserved_mems[i]; return NULL; } diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h index 4de2a24cadc9..34e134bec606 100644 --- a/include/linux/of_reserved_mem.h +++ b/include/linux/of_reserved_mem.h @@ -32,6 +32,8 @@ typedef int (*reservedmem_of_init_fn)(struct reserved_mem *rmem); #define RESERVEDMEM_OF_DECLARE(name, compat, init) \ _OF_DECLARE(reservedmem, name, compat, init, reservedmem_of_init_fn) +void of_reserved_mem_init(void); + int of_reserved_mem_device_init_by_idx(struct device *dev, struct device_node *np, int idx); int of_reserved_mem_device_init_by_name(struct device *dev, @@ -45,6 +47,8 @@ struct reserved_mem *of_reserved_mem_lookup(struct device_node *np); #define RESERVEDMEM_OF_DECLARE(name, compat, init) \ _OF_DECLARE_STUB(reservedmem, name, compat, init, reservedmem_of_init_fn) +static inline void of_reserved_mem_init(void) { } + static inline int of_reserved_mem_device_init_by_idx(struct device *dev, struct device_node *np, int idx) { From patchwork Fri Nov 19 07:58:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Calvin Zhang X-Patchwork-Id: 12628433 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B95FDC433FE for ; Fri, 19 Nov 2021 08:02:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9D2F361A8C for ; Fri, 19 Nov 2021 08:02:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230477AbhKSIFV (ORCPT ); Fri, 19 Nov 2021 03:05:21 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55962 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229879AbhKSIFU (ORCPT ); Fri, 19 Nov 2021 03:05:20 -0500 Received: from mail-pj1-x102a.google.com (mail-pj1-x102a.google.com [IPv6:2607:f8b0:4864:20::102a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 13434C061574; Fri, 19 Nov 2021 00:02:19 -0800 (PST) Received: by mail-pj1-x102a.google.com with SMTP id np6-20020a17090b4c4600b001a90b011e06so8132322pjb.5; Fri, 19 Nov 2021 00:02:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=qOCx5sFVE+zhsZMFm7VYYi5j9KabUFYLGScDeGkNxio=; b=nzW89fNZIaeGG7iFC/anmbyYxdYeiIPsY0WyiJL9dBOt/8uw3ODbBglPEFVbBiYTFV 0pv6LksmsP2oSI7akfzeUVVDy20WgJ8k3Rv/wn0P8mO0aNHHtrwk7Uq1DAm2tz0pk8FA pyHsLEzmZnvO6aptkJL6vJeOlrnGVjQ8DlD967ddxsYJ1T8QRmI3cN0eGcPyOLxdkh7J JFWJebETXfh0MEmv7iOioLeT+GLXWL8dQGOU7S+PWH74qRoFtdGbVE6oXI0KrvG0FTVd +teDlDj3djGGS3rhXtJn8bFeiCJlF9gtWq6C9oZE6cyVc4LO5QXagcnEvn69nlQBAycU pkgQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=qOCx5sFVE+zhsZMFm7VYYi5j9KabUFYLGScDeGkNxio=; b=Or/zsPK1wi4mdi+WX5LKyzzasmMEHIcWIqCQKbMDRBf/PeHPN81krtUEJOsuHgyd0E 5tVYqtGbcva+TjH/xHuS1nahHgLTaq8fstDFFsFW6UMJ9QD6V465XAvTCYtNzht820sy KBXmCBDxNnbVtz6CX0JeSpZLLWCeHug0GrXvRzlu+IkZjHegOnFqVOvREfxR+4NjbYj/ 0gtYdGtSxhaT9fIzakg3WXquwjl6bdrPFbd2m4J00BExm8NY+RY5xDhFy/ZC4VcCD7zT XtlWmq3u2zkbM8HhfcTasrKrqZehscvqk3uKDn/1qVjzZ+5RctQcbgRsHyr5GCT6kyDk hI8A== X-Gm-Message-State: AOAM532oKIz0FRaE+V5g9pGocBw7DJZNHsHUEr8VJLCYsSItqk1LBQMh ko0y81YlL7dQX5HR2rb9PN0= X-Google-Smtp-Source: ABdhPJxD8TG96sq1MtTt8E+2ENWTqJbXT9h5ZtPUFFHaIxmjzzibkl/E4Joc49HUY6kx/0RfviZh7Q== X-Received: by 2002:a17:902:f209:b0:141:99d1:7cef with SMTP id m9-20020a170902f20900b0014199d17cefmr75711457plc.70.1637308938491; Fri, 19 Nov 2021 00:02:18 -0800 (PST) Received: from localhost.localdomain ([103.99.179.247]) by smtp.gmail.com with ESMTPSA id o6sm1791259pfh.70.2021.11.19.00.01.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 19 Nov 2021 00:02:18 -0800 (PST) From: Calvin Zhang To: Vineet Gupta , Russell King , Catalin Marinas , Will Deacon , Guo Ren , Yoshinori Sato , Thomas Bogendoerfer , Nick Hu , Greentime Hu , Vincent Chen , Dinh Nguyen , Jonas Bonn , Stefan Kristiansson , Stafford Horne , Michael Ellerman , Benjamin Herrenschmidt , Paul Mackerras , Paul Walmsley , Palmer Dabbelt , Albert Ou , Rich Felker , Chris Zankel , Max Filippov , Rob Herring , Frank Rowand , Mike Rapoport , Andrew Morton , David Hildenbrand , Kefeng Wang , Vladimir Isaev , Calvin Zhang , Arnd Bergmann , "Russell King (Oracle)" , "Rafael J. Wysocki" , Guenter Roeck , Marc Zyngier , David Brazdil , Mark Rutland , Andrey Konovalov , Anshuman Khandual , Souptick Joarder , Jinyang He , Mauri Sandberg , Tiezhu Yang , Serge Semin , Alexander Sverdlin , Geert Uytterhoeven , Randy Dunlap , Ley Foon Tan , Andreas Oetken , Christophe JAILLET , Christophe Leroy , Ganesh Goudar , Markus Elfring , Andy Shevchenko , "Aneesh Kumar K.V" , Atish Patra , Anup Patel , Nick Kossifidis , Alexandre Ghiti , Vitaly Wool Cc: Wolfram Sang , Lee Jones , Guo Ren , Rob Herring , Zhang Yunkai , Palmer Dabbelt , linux-snps-arc@lists.infradead.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-csky@vger.kernel.org, uclinux-h8-devel@lists.sourceforge.jp, linux-mips@vger.kernel.org, openrisc@lists.librecores.org, linuxppc-dev@lists.ozlabs.org, linux-riscv@lists.infradead.org, linux-sh@vger.kernel.org, linux-xtensa@linux-xtensa.org, devicetree@vger.kernel.org Subject: [PATCH 2/2] of: reserved_mem: Remove reserved regions count restriction Date: Fri, 19 Nov 2021 15:58:19 +0800 Message-Id: <20211119075844.2902592-3-calvinzhang.cool@gmail.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211119075844.2902592-1-calvinzhang.cool@gmail.com> References: <20211119075844.2902592-1-calvinzhang.cool@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org 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/openrisc/kernel/setup.c b/arch/openrisc/kernel/setup.c index 0cd04d936a7a..6830bd110ac4 100644 --- a/arch/openrisc/kernel/setup.c +++ b/arch/openrisc/kernel/setup.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -299,6 +300,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(); + *cmdline_p = boot_command_line; printk(KERN_INFO "OpenRISC Linux -- http://openrisc.io\n"); diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 4f1322b65760..1902b4472991 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -840,6 +841,8 @@ void __init setup_arch(char **cmdline_p) /* Set a half-reasonable default so udelay does something sensible */ loops_per_jiffy = 500000000 / HZ; + of_reserved_mem_init(); + /* Unflatten the device-tree passed by prom_init or kexec */ unflatten_device_tree(); diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c index b42bfdc67482..e3a211cdf5e1 100644 --- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -273,6 +274,7 @@ void __init setup_arch(char **cmdline_p) efi_init(); paging_init(); + of_reserved_mem_init(); #if IS_ENABLED(CONFIG_BUILTIN_DTB) unflatten_and_copy_device_tree(); #else diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 1fcb6659822a..51e85a17c202 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -326,6 +327,8 @@ void __init setup_arch(char **cmdline_p) /* Let earlyprintk output early console messages */ sh_early_platform_driver_probe("earlyprintk", 1, 1); + of_reserved_mem_init(); + #ifdef CONFIG_OF_FLATTREE #ifdef CONFIG_USE_BUILTIN_DTB unflatten_and_copy_device_tree(); diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index 8db20cfb44ab..527d425490fd 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c @@ -25,6 +25,7 @@ #include #include #include +#include #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) # include @@ -356,6 +357,7 @@ void __init setup_arch(char **cmdline_p) parse_early_param(); bootmem_init(); kasan_init(); + of_reserved_mem_init(); unflatten_and_copy_device_tree(); #ifdef CONFIG_SMP diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 445af4e69300..715ce8ec6ac6 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -540,7 +540,6 @@ void __init early_init_fdt_scan_reserved_mem(void) } fdt_scan_reserved_mem(); - of_reserved_mem_init(); fdt_reserve_elfcorehdr(); } diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c index 784cfc5cd251..6dc22a1ad472 100644 --- a/drivers/of/of_reserved_mem.c +++ b/drivers/of/of_reserved_mem.c @@ -26,9 +26,8 @@ #include "of_private.h" -#define MAX_RESERVED_REGIONS 64 -static struct reserved_mem reserved_mems[MAX_RESERVED_REGIONS]; -static int reserved_mem_count; +static struct reserved_mem *reserved_mems; +static int reserved_mem_count, reserved_mem_max_count; static int __init early_init_dt_alloc_reserved_memory_arch(phys_addr_t size, phys_addr_t align, phys_addr_t start, phys_addr_t end, bool nomap, @@ -62,7 +61,7 @@ static void __init fdt_reserved_mem_save_node(unsigned long node, const char *un { struct reserved_mem *rmem = &reserved_mems[reserved_mem_count]; - if (reserved_mem_count == ARRAY_SIZE(reserved_mems)) { + if (reserved_mem_count == reserved_mem_max_count) { pr_err("not enough space for all defined regions.\n"); return; } @@ -200,13 +199,12 @@ static int __init __reserved_mem_check_root(unsigned long node) * __reserved_mem_reserve_reg() - reserve all memory described in 'reg' property */ static int __init __reserved_mem_reserve_reg(unsigned long node, - const char *uname) + const char *uname, bool reserve_only) { 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", &len); @@ -225,30 +223,35 @@ static int __init __reserved_mem_reserve_reg(unsigned long node, base = dt_mem_next_cell(dt_root_addr_cells, &prop); size = dt_mem_next_cell(dt_root_size_cells, &prop); - 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, &base, (unsigned long)(size / SZ_1M)); - else - pr_info("Reserved memory: failed to reserve memory for node '%s': base %pa, size %lu MiB\n", - uname, &base, (unsigned long)(size / SZ_1M)); - - len -= t_len; - if (first) { + if (reserve_only) { + 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, &base, (unsigned long)(size / SZ_1M)); + else + pr_info("Reserved memory: failed to reserve memory for node '%s': base %pa, size %lu MiB\n", + uname, &base, (unsigned long)(size / SZ_1M)); + } else { fdt_reserved_mem_save_node(node, uname, base, size); - first = 0; + break; } + len -= t_len; } return 0; } /* - * fdt_scan_reserved_mem() - scan a single FDT node for reserved memory + * fdt_scan_reserved_mem() - scan /reserved-memory node + * + * Get the max count of regions in the first pass. Early allocator is + * not fully available yet. Store information of reserved region to + * reserved_mems array in the second pass. */ int __init fdt_scan_reserved_mem(void) { - int node, child; + int node, child, regions = 0; const void *fdt = initial_boot_params; + static bool first = true; node = fdt_path_offset(fdt, "/reserved-memory"); if (node < 0) @@ -266,12 +269,19 @@ int __init fdt_scan_reserved_mem(void) if (!of_fdt_device_is_available(fdt, child)) continue; + regions++; 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)) + err = __reserved_mem_reserve_reg(child, uname, first); + if (err == -ENOENT && of_get_flat_dt_prop(child, "size", NULL) && !first) fdt_reserved_mem_save_node(child, uname, 0, 0); } + + if (first) { + reserved_mem_max_count = regions; + first = false; + } + return 0; } @@ -358,6 +368,20 @@ void __init of_reserved_mem_init(void) { int i; + if (!reserved_mem_max_count) + return; + + reserved_mems = memblock_alloc( + sizeof(struct reserved_mem) * reserved_mem_max_count, + SMP_CACHE_BYTES); + if (!reserved_mems) { + reserved_mem_max_count = 0; + pr_err("failed to allocate reserved_mems array.\n"); + return; + } + + fdt_scan_reserved_mem(); + /* check for overlapping reserved regions */ __rmem_check_for_overlap();