Re: [PATCH 08/15] mm: mmzone: MIGRATE_CMA migration type added

From: Hillf Danton
Date: Fri Feb 03 2012 - 09:19:54 EST


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-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/