Replace dynamic allocations in the bootconfig parser with static __initdata buffers. This removes the dependency on memblock being available when bootconfig is parsed, which is a prerequisite for moving embedded bootconfig parsing earlier in the boot sequence.
The static buffers are: - xbc_data_buf[XBC_DATA_MAX + 1] (~32KB) for bootconfig text data - xbc_nodes_buf[XBC_NODE_MAX] (64KB) for the parse tree nodes Both are __initdata and freed after init in the kernel. The userspace tools path (tools/bootconfig) also uses the same static buffers, which simplifies the code by removing all #ifdef __KERNEL__ blocks from the parser. Signed-off-by: Breno Leitao <[email protected]> --- lib/bootconfig.c | 56 ++++++++++---------------------------------------------- 1 file changed, 10 insertions(+), 46 deletions(-) diff --git a/lib/bootconfig.c b/lib/bootconfig.c index c470b93d5dbc2..3e529325c90ac 100644 --- a/lib/bootconfig.c +++ b/lib/bootconfig.c @@ -15,12 +15,11 @@ #ifdef __KERNEL__ #include <linux/bug.h> -#include <linux/ctype.h> -#include <linux/errno.h> #include <linux/cache.h> #include <linux/compiler.h> +#include <linux/ctype.h> +#include <linux/errno.h> #include <linux/sprintf.h> -#include <linux/memblock.h> #include <linux/string.h> #ifdef CONFIG_BOOT_CONFIG_EMBED @@ -54,33 +53,12 @@ static const char *xbc_err_msg __initdata; static int xbc_err_pos __initdata; static int open_brace[XBC_DEPTH_MAX] __initdata; static int brace_index __initdata; - -#ifdef __KERNEL__ -static inline void * __init xbc_alloc_mem(size_t size) -{ - return memblock_alloc(size, SMP_CACHE_BYTES); -} - -static inline void __init xbc_free_mem(void *addr, size_t size, bool early) -{ - if (early) - memblock_free(addr, size); - else if (addr) - memblock_free(addr, size); -} - -#else /* !__KERNEL__ */ - -static inline void *xbc_alloc_mem(size_t size) -{ - return calloc(1, size); -} - -static inline void xbc_free_mem(void *addr, size_t size, bool early) -{ - free(addr); -} -#endif +/* + * Static buffers for bootconfig data and nodes. Avoids dynamic allocation + * so bootconfig can be parsed before memblock is available in the kernel. + */ +static char xbc_data_buf[XBC_DATA_MAX + 1] __initdata; +static struct xbc_node xbc_nodes_buf[XBC_NODE_MAX] __initdata; /** * xbc_get_info() - Get the information of loaded boot config @@ -930,11 +908,9 @@ static int __init xbc_parse_tree(void) */ void __init _xbc_exit(bool early) { - xbc_free_mem(xbc_data, xbc_data_size, early); xbc_data = NULL; xbc_data_size = 0; xbc_node_num = 0; - xbc_free_mem(xbc_nodes, sizeof(struct xbc_node) * XBC_NODE_MAX, early); xbc_nodes = NULL; brace_index = 0; } @@ -973,24 +949,12 @@ int __init xbc_init(const char *data, size_t size, const char **emsg, int *epos) return -ERANGE; } - xbc_data = xbc_alloc_mem(size + 1); - if (!xbc_data) { - if (emsg) - *emsg = "Failed to allocate bootconfig data"; - return -ENOMEM; - } + xbc_data = xbc_data_buf; + xbc_nodes = xbc_nodes_buf; memcpy(xbc_data, data, size); xbc_data[size] = '\0'; xbc_data_size = size + 1; - xbc_nodes = xbc_alloc_mem(sizeof(struct xbc_node) * XBC_NODE_MAX); - if (!xbc_nodes) { - if (emsg) - *emsg = "Failed to allocate bootconfig nodes"; - _xbc_exit(true); - return -ENOMEM; - } - ret = xbc_parse_tree(); if (!ret) ret = xbc_verify_tree(); -- 2.52.0
