diff --git a/include/linux/memblock.h b/include/linux/memblock.h index 7643d2dfa959..965eb874fe30 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -25,6 +25,10 @@ extern unsigned long max_pfn; */ extern unsigned long long max_possible_pfn; +#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT +extern int defer_free_memblock(void *unused); +#endif + /** * enum memblock_flags - definition of memory region attributes * @MEMBLOCK_NONE: no special request diff --git a/init/main.c b/init/main.c index 6a83b54d472c..f6c21b2839bf 100644 --- a/init/main.c +++ b/init/main.c @@ -1531,6 +1531,10 @@ static noinline void __init kernel_init_freeable(void) smp_init(); sched_init_smp(); +#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT + kthread_run(defer_free_memblock, NULL, "defer_mem"); +#endif + padata_init(); page_alloc_init_late(); /* Initialize page ext after all struct pages are initialized. */ diff --git a/mm/memblock.c b/mm/memblock.c index 4fae62b0855d..cc03b8e7cc54 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -97,6 +97,26 @@ struct pglist_data __refdata contig_page_data; EXPORT_SYMBOL(contig_page_data); #endif +#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT +static unsigned long defer_start __initdata; +static unsigned long defer_end __initdata; + +#define DEFAULT_DEFER_FREE_BLOCK_SIZE SZ_256M +static unsigned long defer_free_block_size __initdata = + DEFAULT_DEFER_FREE_BLOCK_SIZE; + +static int __init early_defer_free_block_size(char *p) +{ + defer_free_block_size = memparse(p, &p); + + pr_debug("defer_free_block_size = 0x%lx\n", defer_free_block_size); + + return 0; +} + +early_param("defer_free_block_size", early_defer_free_block_size); +#endif + unsigned long max_low_pfn; unsigned long min_low_pfn; unsigned long max_pfn; @@ -1912,6 +1932,28 @@ static void __init __free_pages_memory(unsigned long start, unsigned long end) } } +#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT +int __init defer_free_memblock(void *unused) +{ + if (defer_start == 0) + return 0; + + pr_debug("start = %ld, end = %ld\n", defer_start, defer_end); + + __free_pages_memory(defer_start, defer_end); + + totalram_pages_add(defer_end - defer_start); + + pr_info("%s: size %luM free %luM [%luM - %luM] total %luM\n", __func__, + defer_free_block_size >> 20, + (defer_end - defer_start) >> (20 - PAGE_SHIFT), + defer_end >> (20 - PAGE_SHIFT), + defer_start >> (20 - PAGE_SHIFT), + totalram_pages() >> (20 - PAGE_SHIFT)); + return 0; +} +#endif + static unsigned long __init __free_memory_core(phys_addr_t start, phys_addr_t end) { @@ -1922,6 +1964,15 @@ static unsigned long __init __free_memory_core(phys_addr_t start, if (start_pfn >= end_pfn) return 0; +#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT + if ((end - start) > defer_free_block_size) { + defer_start = start_pfn; + defer_end = end_pfn; + + return 0; + } +#endif + __free_pages_memory(start_pfn, end_pfn); return end_pfn - start_pfn;