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:
@@ -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
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user