On 2012-12-11 19:28, Simon Jeons wrote: > On Tue, 2012-12-11 at 11:32 +0800, Tang Chen wrote: >> On 12/11/2012 11:07 AM, Jianguo Wu wrote: >>> On 2012/12/11 10:33, Tang Chen wrote: >>> >>>> This patch introduces a new array zone_movable_limit[] to store the >>>> ZONE_MOVABLE limit from movablecore_map boot option for all nodes. >>>> The function sanitize_zone_movable_limit() will find out to which >>>> node the ranges in movable_map.map[] belongs, and calculates the >>>> low boundary of ZONE_MOVABLE for each node. > > What's the difference between zone_movable_limit[nid] and > zone_movable_pfn[nid]? zone_movable_limit[] is a temporary storage for zone_moveable_pfn[]. It's used to handle a special case if user specifies both movablecore_map and movablecore/kernelcore on the kernel command line.
> >>>> >>>> Signed-off-by: Tang Chen<tangc...@cn.fujitsu.com> >>>> Signed-off-by: Jiang Liu<jiang....@huawei.com> >>>> Reviewed-by: Wen Congyang<we...@cn.fujitsu.com> >>>> Reviewed-by: Lai Jiangshan<la...@cn.fujitsu.com> >>>> Tested-by: Lin Feng<linf...@cn.fujitsu.com> >>>> --- >>>> mm/page_alloc.c | 77 >>>> +++++++++++++++++++++++++++++++++++++++++++++++++++++++ >>>> 1 files changed, 77 insertions(+), 0 deletions(-) >>>> >>>> diff --git a/mm/page_alloc.c b/mm/page_alloc.c >>>> index 1c91d16..4853619 100644 >>>> --- a/mm/page_alloc.c >>>> +++ b/mm/page_alloc.c >>>> @@ -206,6 +206,7 @@ static unsigned long __meminitdata >>>> arch_zone_highest_possible_pfn[MAX_NR_ZONES]; >>>> static unsigned long __initdata required_kernelcore; >>>> static unsigned long __initdata required_movablecore; >>>> static unsigned long __meminitdata zone_movable_pfn[MAX_NUMNODES]; >>>> +static unsigned long __meminitdata zone_movable_limit[MAX_NUMNODES]; >>>> >>>> /* movable_zone is the "real" zone pages in ZONE_MOVABLE are taken from >>>> */ >>>> int movable_zone; >>>> @@ -4340,6 +4341,77 @@ static unsigned long __meminit >>>> zone_absent_pages_in_node(int nid, >>>> return __absent_pages_in_range(nid, zone_start_pfn, zone_end_pfn); >>>> } >>>> >>>> +/** >>>> + * sanitize_zone_movable_limit - Sanitize the zone_movable_limit array. >>>> + * >>>> + * zone_movable_limit is initialized as 0. This function will try to get >>>> + * the first ZONE_MOVABLE pfn of each node from movablecore_map, and >>>> + * assigne them to zone_movable_limit. >>>> + * zone_movable_limit[nid] == 0 means no limit for the node. >>>> + * >>>> + * Note: Each range is represented as [start_pfn, end_pfn) >>>> + */ >>>> +static void __meminit sanitize_zone_movable_limit(void) >>>> +{ >>>> + int map_pos = 0, i, nid; >>>> + unsigned long start_pfn, end_pfn; >>>> + >>>> + if (!movablecore_map.nr_map) >>>> + return; >>>> + >>>> + /* Iterate all ranges from minimum to maximum */ >>>> + for_each_mem_pfn_range(i, MAX_NUMNODES,&start_pfn,&end_pfn,&nid) { >>>> + /* >>>> + * If we have found lowest pfn of ZONE_MOVABLE of the node >>>> + * specified by user, just go on to check next range. >>>> + */ >>>> + if (zone_movable_limit[nid]) >>>> + continue; >>>> + >>>> +#ifdef CONFIG_ZONE_DMA >>>> + /* Skip DMA memory. */ >>>> + if (start_pfn< arch_zone_highest_possible_pfn[ZONE_DMA]) >>>> + start_pfn = arch_zone_highest_possible_pfn[ZONE_DMA]; >>>> +#endif >>>> + >>>> +#ifdef CONFIG_ZONE_DMA32 >>>> + /* Skip DMA32 memory. */ >>>> + if (start_pfn< arch_zone_highest_possible_pfn[ZONE_DMA32]) >>>> + start_pfn = arch_zone_highest_possible_pfn[ZONE_DMA32]; >>>> +#endif >>>> + >>>> +#ifdef CONFIG_HIGHMEM >>>> + /* Skip lowmem if ZONE_MOVABLE is highmem. */ >>>> + if (zone_movable_is_highmem()&& >>> >>> Hi Tang, >>> >>> I think zone_movable_is_highmem() is not work correctly here. >>> sanitize_zone_movable_limit >>> zone_movable_is_highmem<--using movable_zone here >>> find_zone_movable_pfns_for_nodes >>> find_usable_zone_for_movable<--movable_zone is specified here >>> >>> I think Jiang Liu's patch works fine for highmem, please refer to: >>> http://marc.info/?l=linux-mm&m=135476085816087&w=2 >> >> Hi Wu, >> >> Yes, I forgot movable_zone think. Thanks for reminding me. :) >> >> But Liu's patch you just mentioned, I didn't use it because I >> don't think we should skip kernelcore when movablecore_map is specified. >> If these 2 options are not conflict, we should satisfy them both. :) >> >> Of course, I also think Liu's suggestion is wonderful. But I think we >> need more discussion on it. :) >> >> I'll fix it soon. >> Thanks. :) >> >>> >>> Thanks, >>> Jianguo Wu >>> >>>> + start_pfn< arch_zone_lowest_possible_pfn[ZONE_HIGHMEM]) >>>> + start_pfn = arch_zone_lowest_possible_pfn[ZONE_HIGHMEM]; >>>> +#endif >>>> + >>>> + if (start_pfn>= end_pfn) >>>> + continue; >>>> + >>>> + while (map_pos< movablecore_map.nr_map) { >>>> + if (end_pfn<= movablecore_map.map[map_pos].start_pfn) >>>> + break; >>>> + >>>> + if (start_pfn>= movablecore_map.map[map_pos].end_pfn) { >>>> + map_pos++; >>>> + continue; >>>> + } >>>> + >>>> + /* >>>> + * The start_pfn of ZONE_MOVABLE is either the minimum >>>> + * pfn specified by movablecore_map, or 0, which means >>>> + * the node has no ZONE_MOVABLE. >>>> + */ >>>> + zone_movable_limit[nid] = max(start_pfn, >>>> + movablecore_map.map[map_pos].start_pfn); >>>> + >>>> + break; >>>> + } >>>> + } >>>> +} >>>> + >>>> #else /* CONFIG_HAVE_MEMBLOCK_NODE_MAP */ >>>> static inline unsigned long __meminit zone_spanned_pages_in_node(int nid, >>>> unsigned long zone_type, >>>> @@ -4358,6 +4430,10 @@ static inline unsigned long __meminit >>>> zone_absent_pages_in_node(int nid, >>>> return zholes_size[zone_type]; >>>> } >>>> >>>> +static void __meminit sanitize_zone_movable_limit(void) >>>> +{ >>>> +} >>>> + >>>> #endif /* CONFIG_HAVE_MEMBLOCK_NODE_MAP */ >>>> >>>> static void __meminit calculate_node_totalpages(struct pglist_data >>>> *pgdat, >>>> @@ -4923,6 +4999,7 @@ void __init free_area_init_nodes(unsigned long >>>> *max_zone_pfn) >>>> >>>> /* Find the PFNs that ZONE_MOVABLE begins at in each node */ >>>> memset(zone_movable_pfn, 0, sizeof(zone_movable_pfn)); >>>> + sanitize_zone_movable_limit(); >>>> find_zone_movable_pfns_for_nodes(); >>>> >>>> /* Print out the zone ranges */ >>> >>> >>> >>> >> >> -- >> To unsubscribe, send a message with 'unsubscribe linux-mm' in >> the body to majord...@kvack.org. For more info on Linux MM, >> see: http://www.linux-mm.org/ . >> Don't email: <a href=mailto:"d...@kvack.org"> em...@kvack.org </a> > > > > . > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/