On Tue, 2012-12-11 at 11:07 +0800, 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. > > > > Signed-off-by: Tang Chen <tangchen@xxxxxxxxxxxxxx> > > Signed-off-by: Jiang Liu <jiang.liu@xxxxxxxxxx> > > Reviewed-by: Wen Congyang <wency@xxxxxxxxxxxxxx> > > Reviewed-by: Lai Jiangshan <laijs@xxxxxxxxxxxxxx> > > Tested-by: Lin Feng <linfeng@xxxxxxxxxxxxxx> > > --- > > 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 > Hi Jiangguo and Chen, - What's the meaning of zone_movable_is_highmem(), does it mean all zone highmem pages are zone movable pages or .... - dmesg > 0.000000] Zone ranges: > [ 0.000000] DMA [mem 0x00010000-0x00ffffff] > [ 0.000000] Normal [mem 0x01000000-0x373fdfff] > [ 0.000000] HighMem [mem 0x373fe000-0xb6cfffff] > [ 0.000000] Movable zone start for each node > [ 0.000000] Node 0: 0x97800000 Why the start of zone movable is in the range of zone highmem, if all the pages of zone movable are from zone highmem? If the answer is yes, zone movable and zone highmem are in the equal status or not? > I think Jiang Liu's patch works fine for highmem, please refer to: > http://marc.info/?l=linux-mm&m=135476085816087&w=2 > > 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 majordomo@xxxxxxxxx. For more info on Linux MM, > see: http://www.linux-mm.org/ . > Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a> -- To unsubscribe from this list: send the line "unsubscribe linux-doc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html