Hello Marek On Fri, Feb 3, 2012 at 8:18 PM, Marek Szyprowski <m.szyprowski@xxxxxxxxxxx> wrote: > From: Michal Nazarewicz <mina86@xxxxxxxxxx> > > The MIGRATE_CMA migration type has two main characteristics: > (i) only movable pages can be allocated from MIGRATE_CMA > pageblocks and (ii) page allocator will never change migration > type of MIGRATE_CMA pageblocks. > > This guarantees (to some degree) that page in a MIGRATE_CMA page > block can always be migrated somewhere else (unless there's no > memory left in the system). > > It is designed to be used for allocating big chunks (eg. 10MiB) > of physically contiguous memory. Once driver requests > contiguous memory, pages from MIGRATE_CMA pageblocks may be > migrated away to create a contiguous block. > > To minimise number of migrations, MIGRATE_CMA migration type > is the last type tried when page allocator falls back to other > migration types then requested. > > Signed-off-by: Michal Nazarewicz <mina86@xxxxxxxxxx> > Signed-off-by: Marek Szyprowski <m.szyprowski@xxxxxxxxxxx> > Signed-off-by: Kyungmin Park <kyungmin.park@xxxxxxxxxxx> > Tested-by: Rob Clark <rob.clark@xxxxxxxxxx> > Tested-by: Ohad Ben-Cohen <ohad@xxxxxxxxxx> > Tested-by: Benjamin Gaignard <benjamin.gaignard@xxxxxxxxxx> > --- > include/linux/gfp.h | 3 ++ > include/linux/mmzone.h | 38 +++++++++++++++++++---- > mm/Kconfig | 2 +- > mm/compaction.c | 11 +++++-- > mm/page_alloc.c | 78 ++++++++++++++++++++++++++++++++++++++---------- > mm/vmstat.c | 3 ++ > 6 files changed, 108 insertions(+), 27 deletions(-) > > diff --git a/include/linux/gfp.h b/include/linux/gfp.h > index 052a5b6..78d32a7 100644 > --- a/include/linux/gfp.h > +++ b/include/linux/gfp.h > @@ -397,6 +397,9 @@ static inline bool pm_suspended_storage(void) > extern int alloc_contig_range(unsigned long start, unsigned long end); > extern void free_contig_range(unsigned long pfn, unsigned nr_pages); > > +/* CMA stuff */ > +extern void init_cma_reserved_pageblock(struct page *page); > + > #endif > > #endif /* __LINUX_GFP_H */ > diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h > index 650ba2f..82f4fa5 100644 > --- a/include/linux/mmzone.h > +++ b/include/linux/mmzone.h > @@ -35,13 +35,37 @@ > */ > #define PAGE_ALLOC_COSTLY_ORDER 3 > > -#define MIGRATE_UNMOVABLE 0 > -#define MIGRATE_RECLAIMABLE 1 > -#define MIGRATE_MOVABLE 2 > -#define MIGRATE_PCPTYPES 3 /* the number of types on the pcp lists */ > -#define MIGRATE_RESERVE 3 > -#define MIGRATE_ISOLATE 4 /* can't allocate from here */ > -#define MIGRATE_TYPES 5 > +enum { > + MIGRATE_UNMOVABLE, > + MIGRATE_RECLAIMABLE, > + MIGRATE_MOVABLE, > + MIGRATE_PCPTYPES, /* the number of types on the pcp lists */ > + MIGRATE_RESERVE = MIGRATE_PCPTYPES, > +#ifdef CONFIG_CMA > + /* > + * MIGRATE_CMA migration type is designed to mimic the way > + * ZONE_MOVABLE works. Only movable pages can be allocated > + * from MIGRATE_CMA pageblocks and page allocator never > + * implicitly change migration type of MIGRATE_CMA pageblock. > + * > + * The way to use it is to change migratetype of a range of > + * pageblocks to MIGRATE_CMA which can be done by > + * __free_pageblock_cma() function. What is important though > + * is that a range of pageblocks must be aligned to > + * MAX_ORDER_NR_PAGES should biggest page be bigger then > + * a single pageblock. > + */ > + MIGRATE_CMA, > +#endif > + MIGRATE_ISOLATE, /* can't allocate from here */ > + MIGRATE_TYPES > +}; > + > +#ifdef CONFIG_CMA > +# define is_migrate_cma(migratetype) unlikely((migratetype) == MIGRATE_CMA) > +#else > +# define is_migrate_cma(migratetype) false > +#endif > > #define for_each_migratetype_order(order, type) \ > for (order = 0; order < MAX_ORDER; order++) \ > diff --git a/mm/Kconfig b/mm/Kconfig > index e338407..3922002 100644 > --- a/mm/Kconfig > +++ b/mm/Kconfig > @@ -198,7 +198,7 @@ config COMPACTION > config MIGRATION > bool "Page migration" > def_bool y > - depends on NUMA || ARCH_ENABLE_MEMORY_HOTREMOVE || COMPACTION > + depends on NUMA || ARCH_ENABLE_MEMORY_HOTREMOVE || COMPACTION || CMA > help > Allows the migration of the physical location of pages of processes > while the virtual addresses are not changed. This is useful in > diff --git a/mm/compaction.c b/mm/compaction.c > index d5174c4..a6e7c64 100644 > --- a/mm/compaction.c > +++ b/mm/compaction.c > @@ -45,6 +45,11 @@ static void map_pages(struct list_head *list) > } > } > > +static inline bool migrate_async_suitable(int migratetype) Just nitpick, since the helper is not directly related to what async means, how about migrate_suitable(int migrate_type) ? > +{ > + return is_migrate_cma(migratetype) || migratetype == MIGRATE_MOVABLE; > +} > + > /* > * Isolate free pages onto a private freelist. Caller must hold zone->lock. > * If @strict is true, will abort returning 0 on any invalid PFNs or non-free > @@ -277,7 +282,7 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc, > */ > pageblock_nr = low_pfn >> pageblock_order; > if (!cc->sync && last_pageblock_nr != pageblock_nr && > - get_pageblock_migratetype(page) != MIGRATE_MOVABLE) { > + migrate_async_suitable(get_pageblock_migratetype(page))) { Here compaction looks corrupted if CMA not enabled, Mel? btw, Kame-san is not Cced correctly 8;/ Hillf -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html