From mboxrd@z Thu Jan 1 00:00:00 1970 From: Yinghai Lu Subject: [PATCH 01/20] x86: add find_e820_area_node Date: Sun, 21 Mar 2010 00:13:02 -0700 Message-ID: <1269155601-18247-2-git-send-email-yinghai@kernel.org> References: <1269155601-18247-1-git-send-email-yinghai@kernel.org> Return-path: In-Reply-To: <1269155601-18247-1-git-send-email-yinghai@kernel.org> Sender: linux-kernel-owner@vger.kernel.org To: Ingo Molnar , Thomas Gleixner , "H. Peter Anvin" , Andrew Morton , David Miller , Je Cc: "Eric W. Biederman" , linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org, Yinghai Lu List-Id: linux-arch.vger.kernel.org David Miller pointed out that early_res have problem to find node data on correct node when we have node0: [0, 2g), [4g, 6g), [10g, 14g) node1: [6g, 10g), [14g, 18g) the cross node case the problem is there for x86 bits even before we are using early_res for bootmem replacement. after early_res for bootmem replacement, alloc_bootmem_node still can get range on correct node this patch is fixing problem before bootmem or early_res replacement for bootmem. now only user is for x86 64bit numa to find node data. the point is use early_node_map with find_e820_area_node() Signed-off-by: Yinghai Lu --- arch/x86/include/asm/e820.h | 1 + arch/x86/kernel/e820.c | 15 +++++++++++++++ arch/x86/mm/numa_64.c | 4 ++-- include/linux/mm.h | 2 ++ mm/page_alloc.c | 37 +++++++++++++++++++++++-------------- 5 files changed, 43 insertions(+), 16 deletions(-) diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h index 0e22296..b48f371 100644 --- a/arch/x86/include/asm/e820.h +++ b/arch/x86/include/asm/e820.h @@ -111,6 +111,7 @@ extern unsigned long end_user_pfn; extern u64 find_e820_area(u64 start, u64 end, u64 size, u64 align); extern u64 find_e820_area_size(u64 start, u64 *sizep, u64 align); +u64 find_e820_area_node(int nid, u64 start, u64 end, u64 size, u64 align); extern u64 early_reserve_e820(u64 startt, u64 sizet, u64 align); #include diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 740b440..05ee724 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -787,6 +787,21 @@ u64 __init find_e820_area_size(u64 start, u64 *sizep, u64 align) return -1ULL; } +u64 __init find_e820_area_node(int nid, u64 start, u64 end, u64 size, u64 align) +{ + u64 addr; + /* + * need to call this function after e820_register_active_regions + * so early_node_map[] is set + */ + addr = find_memory_core_early(nid, size, align, start, end); + if (addr != -1ULL) + return addr; + + /* fallback, should already have start end in the node range */ + return find_e820_area(start, end, size, align); +} + /* * pre allocated 4k and reserved it in e820 */ diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c index 8948f47..ffc5ad5 100644 --- a/arch/x86/mm/numa_64.c +++ b/arch/x86/mm/numa_64.c @@ -174,7 +174,7 @@ static void * __init early_node_mem(int nodeid, unsigned long start, if (start < (MAX_DMA32_PFN< (MAX_DMA32_PFN< %llx\n", - nid, - ei_start, ei_last, goal, limit, size, - align, addr); + return addr; + } + + return -1ULL; +} #endif - ptr = phys_to_virt(addr); - memset(ptr, 0, size); - reserve_early_without_check(addr, addr + size, "BOOTMEM"); - return ptr; - } +#ifdef CONFIG_NO_BOOTMEM +void * __init __alloc_memory_core_early(int nid, u64 size, u64 align, + u64 goal, u64 limit) +{ + void *ptr; - return NULL; + u64 addr; + + addr = find_memory_core_early(nid, size, align, goal, limit); + + if (addr == -1ULL) + return NULL; + + ptr = phys_to_virt(addr); + memset(ptr, 0, size); + reserve_early_without_check(addr, addr + size, "BOOTMEM"); + return ptr; } #endif -- 1.6.4.2 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from rcsinet12.oracle.com ([148.87.113.124]:30594 "EHLO rcsinet12.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751808Ab0CUHQ6 (ORCPT ); Sun, 21 Mar 2010 03:16:58 -0400 From: Yinghai Lu Subject: [PATCH 01/20] x86: add find_e820_area_node Date: Sun, 21 Mar 2010 00:13:02 -0700 Message-ID: <1269155601-18247-2-git-send-email-yinghai@kernel.org> In-Reply-To: <1269155601-18247-1-git-send-email-yinghai@kernel.org> References: <1269155601-18247-1-git-send-email-yinghai@kernel.org> Sender: linux-arch-owner@vger.kernel.org List-ID: To: Ingo Molnar , Thomas Gleixner , "H. Peter Anvin" , Andrew Morton , David Miller , Jesse Barnes Cc: "Eric W. Biederman" , linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org, Yinghai Lu Message-ID: <20100321071302.gvBT52OLYYzGZWTMc4qSGP9QFpQfI2ONQDUX1M9fo8c@z> David Miller pointed out that early_res have problem to find node data on correct node when we have node0: [0, 2g), [4g, 6g), [10g, 14g) node1: [6g, 10g), [14g, 18g) the cross node case the problem is there for x86 bits even before we are using early_res for bootmem replacement. after early_res for bootmem replacement, alloc_bootmem_node still can get range on correct node this patch is fixing problem before bootmem or early_res replacement for bootmem. now only user is for x86 64bit numa to find node data. the point is use early_node_map with find_e820_area_node() Signed-off-by: Yinghai Lu --- arch/x86/include/asm/e820.h | 1 + arch/x86/kernel/e820.c | 15 +++++++++++++++ arch/x86/mm/numa_64.c | 4 ++-- include/linux/mm.h | 2 ++ mm/page_alloc.c | 37 +++++++++++++++++++++++-------------- 5 files changed, 43 insertions(+), 16 deletions(-) diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h index 0e22296..b48f371 100644 --- a/arch/x86/include/asm/e820.h +++ b/arch/x86/include/asm/e820.h @@ -111,6 +111,7 @@ extern unsigned long end_user_pfn; extern u64 find_e820_area(u64 start, u64 end, u64 size, u64 align); extern u64 find_e820_area_size(u64 start, u64 *sizep, u64 align); +u64 find_e820_area_node(int nid, u64 start, u64 end, u64 size, u64 align); extern u64 early_reserve_e820(u64 startt, u64 sizet, u64 align); #include diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 740b440..05ee724 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -787,6 +787,21 @@ u64 __init find_e820_area_size(u64 start, u64 *sizep, u64 align) return -1ULL; } +u64 __init find_e820_area_node(int nid, u64 start, u64 end, u64 size, u64 align) +{ + u64 addr; + /* + * need to call this function after e820_register_active_regions + * so early_node_map[] is set + */ + addr = find_memory_core_early(nid, size, align, start, end); + if (addr != -1ULL) + return addr; + + /* fallback, should already have start end in the node range */ + return find_e820_area(start, end, size, align); +} + /* * pre allocated 4k and reserved it in e820 */ diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c index 8948f47..ffc5ad5 100644 --- a/arch/x86/mm/numa_64.c +++ b/arch/x86/mm/numa_64.c @@ -174,7 +174,7 @@ static void * __init early_node_mem(int nodeid, unsigned long start, if (start < (MAX_DMA32_PFN< (MAX_DMA32_PFN< %llx\n", - nid, - ei_start, ei_last, goal, limit, size, - align, addr); + return addr; + } + + return -1ULL; +} #endif - ptr = phys_to_virt(addr); - memset(ptr, 0, size); - reserve_early_without_check(addr, addr + size, "BOOTMEM"); - return ptr; - } +#ifdef CONFIG_NO_BOOTMEM +void * __init __alloc_memory_core_early(int nid, u64 size, u64 align, + u64 goal, u64 limit) +{ + void *ptr; - return NULL; + u64 addr; + + addr = find_memory_core_early(nid, size, align, goal, limit); + + if (addr == -1ULL) + return NULL; + + ptr = phys_to_virt(addr); + memset(ptr, 0, size); + reserve_early_without_check(addr, addr + size, "BOOTMEM"); + return ptr; } #endif -- 1.6.4.2