init: defer free large memblock to Buddy allocator when CONFIG_ROCKCHIP_THUNDER_BOOT=y

The physical memory of a system is divided into several types, like
memory reserved for device, for kernel pagetable, etc. The remaining
area is for Buddy allocator. Normally, The memory for Buddy is consist
of different size blocks, so, under meeting the memory request of kernel
booting, we can defer free the large block size to Buddy which can be
done later in work queue in parallel to other kernel threads, and the
size of the large block can be defined in kernel command line

Save boot time about 6ms on 512MB rv1126 evb.

Change-Id: Ie7a8d3122d8d92ad918e8bf680f5949412709f37
Signed-off-by: Simon Xue <xxm@rock-chips.com>
Signed-off-by: Tao Huang <huangtao@rock-chips.com>
This commit is contained in:
Simon Xue
2021-06-21 11:19:42 +08:00
committed by Tao Huang
parent 4498c05042
commit b6cd53a3a2
3 changed files with 59 additions and 0 deletions

View File

@@ -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

View File

@@ -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. */

View File

@@ -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;